package com.uas.search.sort;

import org.apache.lucene.index.BinaryDocValues;
import org.apache.lucene.index.LeafReaderContext;
import org.apache.lucene.search.SimpleFieldComparator;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.uas.search.util.StringUtils;

import java.io.IOException;

/**
 * 默认排序实现
 *
 * @author sunyj
 * @since 2017年7月3日 下午4:27:54
 */
abstract class DefaultFieldComparator extends SimpleFieldComparator<String> {

    protected int AHEAD = -1;
    protected int BEHIND = 1;
    protected int PARALLEL = 0;
    protected int UNKOWN = -2;
    private String fieldname;
    private String[] values;
    private BinaryDocValues binaryDocValues;
    private String top;
    private String bottom;

    private Logger logger = LoggerFactory.getLogger(getClass());

    DefaultFieldComparator(String fieldname, int numHits) {
        this.fieldname = fieldname;
        this.values = new String[numHits];
    }

    @Override
    public int compare(int slot1, int slot2) {
        String value1 = values[slot1];
        String value2 = values[slot2];
        return compare(value1, value2);
    }

    /**
     * @param str1
     * @param str2
     * @return {@link #PARALLEL} 表示并列，{@link #BEHIND} 表示 str1 排在 str2 后面，{@link #AHEAD} 表示排在前面，{@link #UNKOWN} 表示需要进一步判断
     */
    protected int compare(String str1, String str2) {
        if (StringUtils.isEmpty(str1) && StringUtils.isEmpty(str2)) {
            return PARALLEL;
        } else if (StringUtils.isEmpty(str1)) {
            return BEHIND;
        } else if (StringUtils.isEmpty(str2)) {
            return AHEAD;
        }
        return UNKOWN;
    }

    @Override
    public void copy(int slot, int doc) throws IOException {
        values[slot] = binaryDocValues == null ? null : binaryDocValues.get(doc).utf8ToString();
    }

    @Override
    protected void doSetNextReader(LeafReaderContext context) throws IOException {
        binaryDocValues = context.reader().getBinaryDocValues(fieldname);
    }

    @Override
    public String value(int slot) {
        return values[slot];
    }

    @Override
    public void setBottom(int slot) {
        bottom = values[slot];
    }

    @Override
    public int compareBottom(int doc) throws IOException {
        String value = binaryDocValues == null ? null : binaryDocValues.get(doc).utf8ToString();
        return compare(bottom, value);
    }

    @Override
    public int compareTop(int doc) throws IOException {
        String value = binaryDocValues == null ? null : binaryDocValues.get(doc).utf8ToString();
        return compare(top, value);
    }

    @Override
    public void setTopValue(String value) {
        top = value;
    }

}
