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


import com.google.common.base.Function;
import com.google.common.base.Joiner;
import com.google.common.collect.FluentIterable;
import lombok.Data;
import org.apache.commons.lang3.tuple.Pair;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;

/**
 * Queue names.召回队列命名处理
 */
@Data
public class QueueName implements Serializable, Comparable<QueueName> {
    private static final Function<Pair<String, String>, String> MATCH_PATTERN =
            new Function<Pair<String, String>, String>() {
                @Override
                public String apply(Pair<String, String> input) {
                    return input.getLeft() + "=" + input.getRight();
                }
            };
    public static final long DEFAULT_LOCAL_CACHE_TTL = 15 * 60 * 1000;
    private final List<Pair<String, String>> matches = new ArrayList<Pair<String, String>>();
    private final String itemType;
    private final String ordering;
    private final long ttl;

    private String metaChannel;  // meta 渠道

    public long getTTL(){
        return this.ttl;
    }

    public QueueName(String itemType, String ordering) {
        this(itemType, ordering, DEFAULT_LOCAL_CACHE_TTL);
    }

    public QueueName(String itemType, String ordering, long ttl) {
        this.itemType = itemType;
        this.ordering = ordering;
        this.ttl = ttl;
    }

    public static QueueName fromString(String string, long ttl) {
        String[] parts = string.split(":");
        String itemType = parts[0];
        String ordering = parts[parts.length - 1].split("=")[1];

        QueueName result = new QueueName(itemType, ordering, ttl);
        for (int i = 2; i < parts.length - 1; ++i) {
            String[] sides = parts[i].split("=");
            result.addMatch(sides[0], sides[1]);
        }
        return result;
    }

    public static QueueName fromString(String string) {
        return QueueName.fromString(string, DEFAULT_LOCAL_CACHE_TTL);
    }

    public static Pair<String, String> parseMatchPair(String match) {
        String[] arr = match.split("=");
        if (arr.length == 2) {
            return Pair.of(arr[0], arr[1]);
        }
        return Pair.of("", "");
    }

    public QueueName addMatch(String key, String value) {
        if (value == null || value.equals("")) {
            value = "_";
        } else {
            value = value.replace("=", "_");
            value = value.replace(":", "_");
        }
        if (key.equals("channel")) {
            this.setMetaChannel(value);
        }
        matches.add(Pair.of(key, value));
        return this;
    }

    public Iterable<String> getMatches() {
        return FluentIterable.from(matches).transform(MATCH_PATTERN);
    }


    @Override
    public String toString() {
        Iterable<String> matchesString = FluentIterable.from(matches)
                .transform(MATCH_PATTERN);

        return itemType + ":queue:" + Joiner.on(":").join(matchesString) + ":ordering=" + ordering;
    }

    @Override
    public int hashCode() {
        return toString().hashCode();
    }

    @Override
    public boolean equals(Object other) {
        return other instanceof QueueName && ((QueueName) other).toString().equals(toString());
    }

    @Override
    public int compareTo(QueueName other) {
        return other.toString().compareTo(ordering.toString());
    }
}