package com.alibaba.csp.sentinel.dashboard.rule.nacos.processor;

import com.alibaba.csp.sentinel.dashboard.rule.nacos.NacosConfig;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.List;

/**
 * @author Clay
 * @date 2022/11/14
 */
@Component
public class NacosPostProcessorExecute {

    private final Logger logger = LoggerFactory.getLogger(NacosPostProcessorExecute.class);



    @Autowired
    private List<NacosPostProcessor> nacosPostProcessorList;


    public void initNacosConfig(String app, String ip, Integer port) {
        if (NacosConfig.isCluster()) {
            initAloneNacosConfig(app, ip, port);
        } else {
            initClusterNacosConfig(app, ip, port);
        }
    }

    private void initAloneNacosConfig(String app, String ip, Integer port) {
        try {
            for (NacosPostProcessor nacosPostProcessor : nacosPostProcessorList) {
                nacosPostProcessor.initPostProcessor(app, ip, port);
            }
        } catch (Exception e) {
            logger.info("init nacos config error! [{}]", e.getMessage());
        }
    }


    private void initClusterNacosConfig(String app, String ip, Integer port) {
        try {
            for (NacosPostProcessor nacosPostProcessor : nacosPostProcessorList) {
                nacosPostProcessor.initClusterProcessor(app, ip, port);
            }
        } catch (Exception e) {
            logger.info("init nacos config error! [{}]", e.getMessage());
        }
    }


    public boolean publishRules(String app, String ip, Integer port, Class<?> clazz) throws Exception {
        if (NacosConfig.isCluster()) {
            return publishClusterRules(app, ip, port, clazz);
        } else {
            return publishAloneRules(app, ip, port, clazz);
        }
    }


    public <T> List<T> getRules(String app, String ip, Integer port, Class<?> clazz) throws Exception {
        if (NacosConfig.isCluster()) {
            return getClusterRules(app, ip, port, clazz);
        } else {
            return getAloneRules(app, ip, port, clazz);
        }
    }


    private boolean publishAloneRules(String app, String ip, Integer port, Class<?> clazz) throws Exception {
        for (NacosPostProcessor nacosPostProcessor : nacosPostProcessorList) {
            if (nacosPostProcessor.publishRules(app, ip, port, clazz)) {
                return true;
            }
        }
        return false;
    }

    private boolean publishClusterRules(String app, String ip, Integer port, Class<?> clazz) throws Exception {
        for (NacosPostProcessor nacosPostProcessor : nacosPostProcessorList) {
            if (nacosPostProcessor.publishClusterRules(app, ip, port, clazz)) {
                return true;
            }
        }
        return false;
    }

    private <T> List<T> getAloneRules(String app, String ip, Integer port, Class<?> clazz) throws Exception {
        for (NacosPostProcessor nacosPostProcessor : nacosPostProcessorList) {
            List<T> rules = nacosPostProcessor.getRules(app, ip, port, clazz);
            if (null != rules) {
                return rules;
            }
        }
        return null;
    }

    private <T> List<T> getClusterRules(String app, String ip, Integer port, Class<?> clazz) throws Exception {
        for (NacosPostProcessor nacosPostProcessor : nacosPostProcessorList) {
            List<T> rules = nacosPostProcessor.getClusterRules(app, ip, port, clazz);
            if (null != rules) {
                return rules;
            }
        }
        return null;
    }
}
