package com.tzld.piaoquan.ad.engine.service.score.deprecated.container;

import com.alibaba.fastjson.JSONObject;
import com.google.common.cache.CacheBuilder;
import com.google.common.cache.CacheLoader;
import com.google.common.cache.LoadingCache;
import com.tzld.piaoquan.ad.engine.service.remote.FeatureRemoteService;
import com.tzld.piaoquan.recommend.feature.domain.ad.base.AdRankItem;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;
import java.util.*;
import java.util.concurrent.TimeUnit;
import java.util.function.Function;

@Component
public class AdCreativeFeatureContainer {
    private final static Logger log = LoggerFactory.getLogger(AdCreativeFeatureContainer.class);
    @Autowired
    FeatureRemoteService featureRemoteService;
    protected Function<Long, AdRankItem> defaultValueFunc= k -> null;;
    private static LoadingCache<Long, AdRankItem> cache = null;


    public static void putIntoCache(Long key, AdRankItem value) {
        cache.put(key, value);
    }

    @PostConstruct
    public void initCache(){
        cache = CacheBuilder.newBuilder()
                .maximumSize(1000)
                .refreshAfterWrite(10, TimeUnit.MINUTES)
                .expireAfterWrite(10,TimeUnit.MINUTES)
                .expireAfterAccess(10, TimeUnit.MINUTES)
                .concurrencyLevel(5)
                .build(new CacheLoader<Long, AdRankItem>() {
                    @Override
                    public AdRankItem load(Long key) {
                        return AdCreativeFeatureContainer.this.load(key);
                    }

                    @Override
                    public Map<Long, AdRankItem> loadAll(Iterable<? extends Long> keys) {
                        return AdCreativeFeatureContainer.this.loadAll(keys);
                    }
                });
    }

    private AdRankItem load(Long key) {
        AdRankItem feature = getFromCache(key);
        if (feature == null) {
            feature = defaultValueFunc.apply(key);
        }
        log.info("svc=load_from_recommend_feature  id={}", JSONObject.toJSONString(key));
        return feature;
    }

    private AdRankItem getFromCache(Long key) {

        return  featureRemoteService.getAdFeature(key);
    }

    private  Map<Long, AdRankItem> loadAll(Iterable<? extends Long> keys) {
        Iterator<? extends Long> ite = keys.iterator();
        List<String> keyList = new ArrayList<>();
        while (ite.hasNext()) {
            keyList.add(ite.next().toString());
        }
        List<AdRankItem> resultList=featureRemoteService.getAllAdFeatureList(keyList);
        Map<Long, AdRankItem> result = new HashMap<>();
        for (int i = 0; i < resultList.size(); i++) {
            result.put(resultList.get(i).getAdId(),resultList.get(i));
        }
        log.info("svc=load_from_recommend_feature  idList={}", JSONObject.toJSONString(keyList));
        return result;
    }
    public Map<Long, AdRankItem>  getAll(List<Long> creativeIds) {
        try {
            return cache.getAll(creativeIds);
        } catch (Exception e) {
            log.error("get all failed {}", e);
        }
        return Collections.emptyMap();
    }

    public AdRankItem get(Long creativeIds) {
        assert cache != null;
        try {
            return cache.getUnchecked(creativeIds);
        } catch (Exception e) {
            log.error("get local cache error", e);
        }
        return null;
    }
}
