package com.tzld.piaoquan.recommend.server.service;

import com.ctrip.framework.apollo.spring.annotation.ApolloJsonValue;
import com.tzld.piaoquan.recommend.server.common.enums.RootSessionIdLayer;
import com.tzld.piaoquan.recommend.server.model.RootSessionIdExpConfig;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.collections4.MapUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Set;

@Slf4j
@Service
public class ExperimentService {

    @ApolloJsonValue("${root.session.id.exp.layer.config:{}}")
    private Map<String, List<RootSessionIdExpConfig>> rootSessionIdExpConfigMap;

    /**
     * 是否命中某个算法层实验号
     *
     * @param appType       appType
     * @param rootSessionId rootSessionId
     * @param abExpCodes    AB实验号集合
     * @param expCode       要判断的实验号
     * @return true: 命中要判断的实验号; false: 未命中要判断的实验号
     */
    public boolean judgeHitAlgoExp(int appType, String rootSessionId, Set<String> abExpCodes, String expCode) {
        return judgeHitExp(RootSessionIdLayer.algo, appType, rootSessionId, abExpCodes, expCode);
    }

    public boolean judgeHitExp(RootSessionIdLayer layer, int appType, String rootSessionId, Set<String> abExpCodes, String expCode) {
        try {
            // 要判断的实验号为空，直接返回false
            if (StringUtils.isBlank(expCode) || Objects.isNull(layer)) {
                return false;
            }
            // 先判断AB实验号集合中，是否包含要判断的实验号
            if (CollectionUtils.isNotEmpty(abExpCodes) && abExpCodes.contains(expCode)) {
                return true;
            }
            if (MapUtils.isEmpty(rootSessionIdExpConfigMap) || StringUtils.isBlank(rootSessionId)) {
                return false;
            }
            List<RootSessionIdExpConfig> rootSessionIdExpConfigs = rootSessionIdExpConfigMap.get(layer.getLayer());
            if (CollectionUtils.isEmpty(rootSessionIdExpConfigs)) {
                return false;
            }

            // 根据appType和rootSessionId尾号，判断是否命中实验
            String cleanId = rootSessionId.replace("-", "");
            if (cleanId.length() < layer.getTailIndex()) {
                return false;
            }
            String tail = String.valueOf(cleanId.charAt(cleanId.length() - layer.getTailIndex()));
            for (RootSessionIdExpConfig config : rootSessionIdExpConfigs) {

                if (CollectionUtils.isEmpty(config.getExpCodes())) {
                    continue;
                }
                if (CollectionUtils.isEmpty(config.getAppType())) {
                    continue;
                }
                if (CollectionUtils.isEmpty(config.getTail())) {
                    continue;
                }


                if (config.getAppType().contains(appType)
                        && config.getTail().contains(tail)
                        && config.getExpCodes().contains(expCode)) {
                    return true;
                }
            }

            return false;
        } catch (Exception e) {
            log.error("RootSessionId tail experiment judge hit exp error layer: {}, appType: {}, rootSessionId: {}, abExpCodes: {}, expCode: {}",
                    layer, appType, rootSessionId, abExpCodes, expCode, e
            );
            return false;
        }
    }
}
