package com.tzld.piaoquan.recommend.server.implement.recall;


import com.google.common.cache.CacheBuilder;
import com.google.common.cache.CacheLoader;
import com.google.common.cache.LoadingCache;
import com.google.common.collect.Lists;
import com.tzld.piaoquan.recommend.server.framework.candidiate.Candidate;
import com.tzld.piaoquan.recommend.server.framework.common.User;
import com.tzld.piaoquan.recommend.server.framework.recaller.AbstractFilter;
import com.tzld.piaoquan.recommend.server.framework.recaller.FilterConfigInfo;
import com.tzld.piaoquan.recommend.server.gen.recommend.RecommendRequest;
import com.tzld.piaoquan.recommend.server.model.Video;
import com.tzld.piaoquan.recommend.server.repository.WxVideoTagRel;
import com.tzld.piaoquan.recommend.server.repository.WxVideoTagRelRepository;
import com.tzld.piaoquan.recommend.server.util.CommonCollectionUtils;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang.math.NumberUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;

import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.Set;
import java.util.concurrent.TimeUnit;

public class TagFilter extends AbstractFilter<Video> {

    @Autowired
    private WxVideoTagRelRepository repository;

    @Value("${video.filter.tagids:}")
    private String videoFilterTagIds;

    private LoadingCache<Long, Set<Long>> videoTagCache = CacheBuilder.newBuilder()
            .maximumSize(100)
            .refreshAfterWrite(60, TimeUnit.SECONDS)
            .expireAfterWrite(60, TimeUnit.SECONDS)
            .expireAfterAccess(60, TimeUnit.SECONDS)
            .build(new CacheLoader<Long, Set<Long>>() {
                @Override
                public Set<Long> load(Long tagId) {
                    List<WxVideoTagRel> rels = repository.findAllByTagId(tagId);
                    return CommonCollectionUtils.toSet(rels, WxVideoTagRel::getVideoId);
                }
            });


    public TagFilter(FilterConfigInfo filterConfigInfo,
                     RecommendRequest recommendRequest,
                     User user) {
        super(filterConfigInfo, recommendRequest, user);

        if (org.apache.commons.lang.StringUtils.isNotBlank(this.videoFilterTagIds)) {
            String[] tags = this.videoFilterTagIds.split(",");
            for (String tag : tags) {
                if (org.apache.commons.lang.StringUtils.isBlank(tag)) {
                    continue;
                }
                this.videoTagCache.getUnchecked(NumberUtils.toLong(tag));
            }
        }
    }

    @Override
    public void doFilter(Candidate candidate, List<Video> t) {
        if (CollectionUtils.isEmpty(t)) {
            return;
        }
        List<Video> videos = Lists.newArrayList();
        for (Video video : t) {
            if (!hasVideoRelTagId(video.getVideoId(), videoFilterTagIds)) {
                videos.add(video);
            }
        }
        t.removeAll(videos);
    }

    private boolean hasVideoRelTagId(Long videoId, String videoFilterTagIds) {
        // TODO 主要是涉政标签
        List<Long> tagIds = new ArrayList<>();

        String[] tags = videoFilterTagIds.split(",");
        for (String tag : tags) {
            if (Objects.isNull(tag) || Objects.equals("", tag)) {
                continue;
            }
            tagIds.add(Long.parseLong(tag));
        }

        for (Long tagId : tagIds) {
            if (Objects.isNull(videoId) || videoId <= 0L || Objects.isNull(tagId) || tagId <= 0L) {
                return false;
            }
            Set<Long> videos = this.videoTagCache.getUnchecked(tagId);
            if (CollectionUtils.isEmpty(videos)) {
                return false;
            }
            return videos.contains(videoId);
        }
        return false;
    }

}
