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

import com.google.common.cache.CacheBuilder;
import com.google.common.cache.CacheLoader;
import com.google.common.cache.LoadingCache;
import com.google.common.reflect.TypeToken;
import com.tzld.piaoquan.recommend.server.util.JSONUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;

/**
 * @author dyp
 */
@Service
@Slf4j
public class FlowPoolConfigService {
    @Autowired
    @Qualifier("redisTemplate")
    private RedisTemplate<String, String> redisTemplate;

    // TODO 这些配置可以用配置中心么？
    // {"control_group": [], "experimental_flow_set_level": [10, 11, 12, 13, 14, 15, 16, 17], "experimental_flow_set_level_score": [9, 18]}
    private LoadingCache<String, Map<String, List<Integer>>> flowPoolConfigCache = CacheBuilder.newBuilder()
            .maximumSize(10)
            .refreshAfterWrite(60, TimeUnit.SECONDS)
            .expireAfterWrite(60, TimeUnit.SECONDS)
            .expireAfterAccess(60, TimeUnit.SECONDS)
            .build(new CacheLoader<String, Map<String, List<Integer>>>() {
                @Override
                public Map<String, List<Integer>> load(String key) throws Exception {
                    String value = redisTemplate.opsForValue().get(key);
                    if (StringUtils.isEmpty(value)) {
                        value = "{\"control_group\": [7, 8, 9, 10, 11, 12, 13, 14, 15, 16],\n" +
                                "                           \"experimental_flow_set_level\": [],\n" +
                                "                           \"experimental_flow_set_level_score\": []}";
                    }
                    return JSONUtils.fromJson(value, new TypeToken<Map<String, List<Integer>>>() {
                    }, Collections.emptyMap());
                }
            });

    private LoadingCache<String, Map<String, Double>> levelWeightConfigCache = CacheBuilder.newBuilder()
            .maximumSize(10)
            .refreshAfterWrite(60, TimeUnit.SECONDS)
            .expireAfterWrite(60, TimeUnit.SECONDS)
            .expireAfterAccess(60, TimeUnit.SECONDS)
            .build(new CacheLoader<String, Map<String, Double>>() {
                @Override
                public Map<String, Double> load(String key) throws Exception {
                    String value = redisTemplate.opsForValue().get(key);
                    if (StringUtils.isEmpty(value)) {
                        value = "level_weight = {\"1\": 1, \"2\": 1, \"3\": 1, \"4\": 1, \"5\": 1, \"6\": 1}";
                    }
                    return JSONUtils.fromJson(value, new TypeToken<Map<String, Double>>() {
                    }, Collections.emptyMap());
                }
            });

    public Map<String, List<Integer>> getFlowPoolConfig() {
        try {
            return flowPoolConfigCache.get("flow:pool:abtest:config");
        } catch (ExecutionException e) {
            log.error("getFlowPoolConfig error", e);
            return Collections.emptyMap();
        }
    }

    public Map<String, Double> getLevelWeight() {
        try {
            return levelWeightConfigCache.get("flow:pool:level:recommend:weight");
        } catch (ExecutionException e) {
            log.error("getFlowPoolConfig error", e);
            return Collections.emptyMap();
        }
    }
}
