package com.tzld.piaoquan.recommend.server.framework.merger;


import com.tzld.piaoquan.recommend.server.common.base.RankItem;
import com.tzld.piaoquan.recommend.server.framework.candidiate.Candidate;
import com.tzld.piaoquan.recommend.server.framework.candidiate.QueueName;
import com.tzld.piaoquan.recommend.server.framework.common.User;
import com.tzld.piaoquan.recommend.server.gen.recommend.RecommendRequest;
import org.apache.commons.lang3.tuple.Pair;

import java.util.HashMap;
import java.util.List;
import java.util.Map;


/**
 * 定义召回下子队列的Queue 融合信息
 */
public abstract class IndexCandidateQueue extends StrategyQueue {

    protected Map<String, Candidate> myCandidates = new HashMap<String, Candidate>();

    public IndexCandidateQueue(StrategyQueueInfo strategyQueueInfo, StrategyQueueConfig strategyQueueConfig) {
        super(strategyQueueInfo, strategyQueueConfig);
    }

    public abstract int addCandidateKey(Map<String, Candidate> candidates, int recallNum, User user, RecommendRequest requestData, int requestIndex, int expId);


    @Override
    public int doMerge(final Map<String, Pair<MergeRule, List<RankItem>>> rankerItemsListMap, int recNum, User user, RecommendRequest requestData, int requestIndex, int expId) {
        // TODO: sublist by every queue
        return MergeUtils.simpleMergeWithProtection(items, rankerItemsListMap, recNum, expId);
    }

    @Override
    public int candidate(final Map<String, Candidate> candidateMap, final int recallNum, final User user, final RecommendRequest requestData, final int requestIndex, final int expId) {
        myCandidates.clear();
        int n = addCandidateKey(candidateMap, recallNum, user, requestData, requestIndex, expId);
        candidateMap.putAll(myCandidates);

        return n;
    }

    protected int addCandidateKey(Map<String, Candidate> candidates, String key, int num, String queue) {
        if (candidates.containsKey(key)) {
            return 0;
        } else {
            Candidate candidate = new Candidate();
            candidate.setCandidateKey(key);
            candidate.setCandidateNum(num);
            candidate.setMergeQueueName(queue);
            candidates.put(key, candidate);
            return num;
        }
    }

    protected int addCandidateKey(Map<String, Candidate> candidates, QueueName queueName, int num, String queue) {
        return this.addCandidateKey(candidates, queueName, num, queue, true, true, true);
    }

    protected int addCandidateKey(Map<String, Candidate> candidates, QueueName queueName, int num, String queue, boolean needScore, boolean needPornRank) {
        return this.addCandidateKey(candidates, queueName, num, queue, needScore, needPornRank, true);
    }

    protected int addCandidateKey(Map<String, Candidate> candidates, QueueName queueName, int num, String queue, boolean needScore, boolean needPornRank, boolean needExposeHistoryFilter) {
        if (candidates.containsKey(queueName.toString())) {
            return 0;
        } else {
            Candidate candidate = new Candidate();
            candidate.setCandidateKey(queueName.toString());
            candidate.setCandidateNum(num);
            candidate.setMergeQueueName(queue);
            candidates.put(queueName.toString(), candidate);
            return num;
        }
    }

    @Override
    public String toString() {
        return "IndexCandidateQueue{" +
                "myCandidates=" + myCandidates +
                ", rankerItemsList=" + rankerItemsList +
                ", children=" + children +
                ", items=" + items +
                '}';
    }
}
