package com.fs.fssync.listener;

import cn.hutool.extra.spring.SpringUtil;
import com.alibaba.fastjson.JSON;
import com.fs.fssync.config.SpringContextHolder;
import com.fs.fssync.sink.CdcSinkStrategy;
import lombok.extern.slf4j.Slf4j;
import org.apache.flink.configuration.Configuration;
import org.apache.flink.streaming.api.functions.sink.RichSinkFunction;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.stereotype.Component;

import java.io.Serializable;
import java.util.Map;

/**
 * Flink CDC 数据处理
 *
 * @author jokey
 * @since 2024-3-14
 */
@Slf4j
public class CustomSink extends RichSinkFunction<String> implements Serializable {

    @Override
    public void invoke(String value, Context context) {
        log.info("收到变更原始数据:{}", value);
        try {
            // 从JSON中提取表名信息
            String source = JSON.parseObject(value).getString("source");
            String table = JSON.parseObject(source).getString("table");

            // 根据表名查找对应的策略
            processBySinkStrategy(table, value);
        } catch (Exception e) {
            log.error("处理CDC数据失败", e);
        }
    }

    private void processBySinkStrategy(String table, String value) {
        // 获取所有实现了CdcSinkStrategy的Bean
        Map<String, CdcSinkStrategy> strategies =
                SpringContextHolder.getApplicationContext().getBeansOfType(CdcSinkStrategy.class);


        for (CdcSinkStrategy strategy : strategies.values()) {
            try {
                if (isStrategyForTable(strategy, table)) {
                    strategy.process(value);
                    return;
                }
            } catch (Exception e) {
                log.error("策略处理失败", e);
            }
        }

        log.warn("未找到表 {} 的处理策略", table);
    }

    private boolean isStrategyForTable(CdcSinkStrategy strategy, String table) {

        return strategy.canHandle(table.toLowerCase());
    }
}
