package com.lanyuanxiaoyao.service.sync.functions;

import cn.hutool.core.map.MapUtil;
import com.lanyuanxiaoyao.service.common.Constants;
import com.lanyuanxiaoyao.service.common.entity.FlinkJob;
import com.lanyuanxiaoyao.service.common.entity.Record;
import com.lanyuanxiaoyao.service.common.entity.TableMeta;
import com.lanyuanxiaoyao.service.sync.configuration.GlobalConfiguration;
import com.lanyuanxiaoyao.service.sync.utils.MetricsUtils;
import java.util.Map;
import java.util.function.Function;
import org.apache.flink.api.common.functions.RichFilterFunction;
import org.apache.flink.configuration.Configuration;
import org.apache.flink.metrics.Counter;

/**
 * 操作类型过滤算子
 *
 * @author ZhangJiacheng
 * @date 2022-06-12
 */
public class OperationTypeFilter extends RichFilterFunction<Record> {
    private final FlinkJob flinkJob;
    private final TableMeta tableMeta;

    private transient Counter insertCounter;
    private transient Counter updateCounter;
    private transient Counter deleteCounter;
    private transient Counter ddlCounter;
    private transient Counter unknownCounter;

    public OperationTypeFilter(GlobalConfiguration globalConfiguration, FlinkJob flinkJob, TableMeta tableMeta) {
        this.flinkJob = flinkJob;
        this.tableMeta = tableMeta;
    }

    @Override
    public void open(Configuration parameters) throws Exception {
        super.open(parameters);

        // 初始化指标
        insertCounter = MetricsUtils.counter(getRuntimeContext(), flinkJob, tableMeta, Constants.METRICS_SYNC_SOURCE_OPERATION_TYPE_RECEIVE_INSERT);
        updateCounter = MetricsUtils.counter(getRuntimeContext(), flinkJob, tableMeta, Constants.METRICS_SYNC_SOURCE_OPERATION_TYPE_RECEIVE_UPDATE);
        deleteCounter = MetricsUtils.counter(getRuntimeContext(), flinkJob, tableMeta, Constants.METRICS_SYNC_SOURCE_OPERATION_TYPE_RECEIVE_DELETE);
        ddlCounter = MetricsUtils.counter(getRuntimeContext(), flinkJob, tableMeta, Constants.METRICS_SYNC_SOURCE_OPERATION_TYPE_RECEIVE_DDL);
        unknownCounter = MetricsUtils.counter(getRuntimeContext(), flinkJob, tableMeta, Constants.METRICS_SYNC_SOURCE_OPERATION_TYPE_RECEIVE_UNKNOWN);
    }

    @Override
    public boolean filter(Record record) {
        String opType = record.getStatement().getOpType();
        switch (opType) {
            case Constants.INSERT:
                insertCounter.inc();
                break;
            case Constants.UPDATE:
                updateCounter.inc();
                break;
            case Constants.DELETE:
                deleteCounter.inc();
                break;
            case Constants.DDL:
                ddlCounter.inc();
                break;
            default:
                unknownCounter.inc();
        }
        return !Constants.DDL.equals(record.getStatement().getOpType());
    }
}
