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

import com.ctrip.framework.apollo.spring.annotation.ApolloJsonValue;
import com.google.common.cache.CacheBuilder;
import com.google.common.cache.CacheLoader;
import com.google.common.cache.LoadingCache;
import com.tzld.piaoquan.recommend.server.repository.WxVideoTagRel;
import com.tzld.piaoquan.recommend.server.repository.WxVideoTagRelRepository;
import com.tzld.piaoquan.recommend.server.service.filter.FilterParam;
import com.tzld.piaoquan.recommend.server.service.filter.FilterStrategy;
import com.tzld.piaoquan.recommend.server.util.CommonCollectionUtils;
import com.tzld.piaoquan.recommend.server.util.JSONUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.Collections;
import java.util.List;
import java.util.Set;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

/**
 * @author dyp
 */
@Component
@Slf4j
public class RiskVideoStrategy implements FilterStrategy {

    @ApolloJsonValue("${risk.video.tag:[]}")
    private List<Long> riskVideoTagIds;

    @Autowired
    private WxVideoTagRelRepository repository;
    // 内存持久保存不淘汰
    private LoadingCache<String, Set<Long>> riskVideoCache = CacheBuilder.newBuilder()
            .maximumSize(10)
            .refreshAfterWrite(60, TimeUnit.SECONDS)
            .expireAfterWrite(60, TimeUnit.SECONDS)
            .expireAfterAccess(60, TimeUnit.SECONDS)
            .build(new CacheLoader<String, Set<Long>>() {
                @Override
                public Set<Long> load(String key) {
                    List<WxVideoTagRel> rels = repository.findAllByTagIdIn(riskVideoTagIds);
                    return CommonCollectionUtils.toSet(rels, WxVideoTagRel::getVideoId);
                }
            });

    @Override
    public List<Long> filter(FilterParam param) {
        if (param == null) {
            return Collections.emptyList();
        }
        if (CollectionUtils.isEmpty(param.getVideoIds())) {
            return param.getVideoIds();
        }

        if (!param.isRiskUser()) {
            return param.getVideoIds();
        }

        Set<Long> riskVids = riskVideoCache.getUnchecked("");
        List<Long> videoIds = param.getVideoIds().stream()
                .filter(l -> !riskVids.contains(l))
                .collect(Collectors.toList());

        log.info("RiskVideoStrategy \t param={} \t before={} \t after={}",
                JSONUtils.toJson(param),
                JSONUtils.toJson(param.getVideoIds()),
                JSONUtils.toJson(videoIds));

        return videoIds;
    }
}
