package com.tax.user.service.rules.manager;

import com.google.common.collect.Maps;
import com.tax.user.model.SysRule;
import com.tax.user.service.rules.RuleCheckI;
import com.tax.user.service.rules.support.CheckIfInBlackService;
import com.tax.user.service.rules.support.CheckIpInWhiteService;
import com.yxcheng.token.common.model.JsonResult;
import com.yxcheng.token.common.model.RuleModel;
import com.yxcheng.token.utils.SpringUtil;
import org.apache.commons.collections.CollectionUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.stream.Collectors;

@Component
public class RulesManager {

    protected static Logger logger = LoggerFactory.getLogger(RulesManager.class);

    static Map<String, RuleCheckI> map = new HashMap<String, RuleCheckI>();

    static AtomicBoolean flag = new AtomicBoolean(false);


    public static void init() {
        if (flag.compareAndSet(false, true)) {
            map.put("ipInWhitelist", SpringUtil.getBean(CheckIpInWhiteService.class));
            map.put("taxnoInBlacklist", SpringUtil.getBean(CheckIfInBlackService.class));
        }
    }

    public static RuleCheckI getService(Map<String, RuleCheckI> ruleCheckIMap, String ruleCode) {
        return ruleCheckIMap.get(ruleCode);
    }

    private static Map<String, RuleCheckI> loadRules(List<SysRule> rules) {
        Map<String, RuleCheckI> ruleCheckIMap = Maps.newHashMap();
        for (SysRule rule : rules) {
            RuleCheckI ruleService = null;
            try {
                ruleService = (RuleCheckI) SpringUtil.getBean(rule.getRuleClass());
            } catch (Exception e) {
                e.printStackTrace();
                logger.error("loadRules " + rule.getRuleClass() + " is failure!" + e.getMessage());
            }
            ruleCheckIMap.put(rule.getRuleCode(), ruleService);
        }
        return ruleCheckIMap;
    }

    public static boolean checkRule(List<SysRule> rules, RuleModel model, JsonResult<String> result) {
        //如果为空目前不校验
        if (CollectionUtils.isEmpty(rules)) {
            return true;
        }
        //加载此用户需要校验的规则
        Map<String, RuleCheckI> ruleCheckIMap = loadRules(rules);
        //排序
        rules.stream().sorted(Comparator.comparingInt(SysRule::getRuleOrder))
                .collect(Collectors.toList());
        for (SysRule sysRule : rules) {
            RuleCheckI service = getService(ruleCheckIMap, sysRule.getRuleCode());
            if (!service.check(model, result)) {
                logger.info("RulesManager result code:{},msg:{}", result.getErrorCode(), result.getMessage());
                return false;
            }
        }
        return true;
    }
}
