package com.lanyuanxiaoyao.service.sync.functions;

import com.lanyuanxiaoyao.service.common.Constants;
import com.lanyuanxiaoyao.service.common.entity.FlinkJob;
import com.lanyuanxiaoyao.service.common.entity.TableMeta;
import com.lanyuanxiaoyao.service.common.utils.TableMetaHelper;
import com.lanyuanxiaoyao.service.sync.configuration.GlobalConfiguration;
import com.lanyuanxiaoyao.service.sync.configuration.TraceWriteStatus;
import com.lanyuanxiaoyao.service.sync.utils.StatusUtils;
import java.io.Serializable;
import java.util.List;
import org.apache.hudi.client.WriteStatus;
import org.apache.hudi.common.model.HoodieCommitMetadata;
import org.apache.hudi.sink.compact.CompactEventHandler;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * 压缩事件处理
 *
 * @author ZhangJiacheng
 * @date 2022-06-15
 */
public class CompactionEventHandler implements CompactEventHandler, Serializable {
    private static final Logger logger = LoggerFactory.getLogger(CompactionEventHandler.class);

    private final GlobalConfiguration configuration;
    private final FlinkJob flinkJob;
    private final TableMeta tableMeta;

    public CompactionEventHandler(GlobalConfiguration configuration, FlinkJob flinkJob, TableMeta tableMeta) {
        this.configuration = configuration;
        this.flinkJob = flinkJob;
        this.tableMeta = tableMeta;
    }

    @Override
    public void failure(String instant) {
    }

    @Override
    public void success(String instant, List<WriteStatus> statuses, HoodieCommitMetadata metadata) {
        StatusUtils.compactionCommit(configuration, flinkJob, tableMeta, instant, metadata);
        logger.info("WriteStatus: {}", statuses);
        if (TableMetaHelper.existsTag(tableMeta, Constants.TAGS_TRACE_LATEST_OP_TS)) {
            Long max = statuses.stream()
                    .map(status -> {
                        if (status instanceof TraceWriteStatus) {
                            TraceWriteStatus s = (TraceWriteStatus) status;
                            return s.getLatestOpts();
                        }
                        return 0L;
                    })
                    .max(Long::compare)
                    .orElse(0L);
            logger.info("Latest op ts: {}", max);
            StatusUtils.compactionLatestOpTs(configuration, flinkJob, tableMeta, max);
        }
    }

    @Override
    public void closed(String message, Exception exception) {
        StatusUtils.compactionFinish(configuration, flinkJob, tableMeta, message, exception);
    }
}
