package mobvista.dmp.datasource.ga.mapreduce.vo;


import org.apache.hadoop.io.Text;
import org.apache.hadoop.io.WritableComparable;
import org.apache.hadoop.io.WritableComparator;
import org.apache.hadoop.io.WritableUtils;
import org.apache.hadoop.mapreduce.Partitioner;

import java.io.DataInput;
import java.io.DataOutput;
import java.io.IOException;


public class TextPairSort implements WritableComparable<TextPairSort>
{
    private Text first;
    private Text second;
    private Text isAsc = new Text("true");

    public TextPairSort()
    {
        set(new Text(), new Text());
    }

    public TextPairSort(String first, String second)
    {
        this.set(new Text(first), new Text(second));
    }

    public void set(Text first, Text second)
    {
        this.first = first;
        this.second = second;
    }

    public void set(Text first, Text second, Text isAsc)
    {
        this.first = first;
        this.second = second;
        this.isAsc = isAsc;
    }

    public void set(String first, String second)
    {
        this.set(new Text(first), new Text(second));
    }
    public void set(String first, String second, String isAsc)
    {
        this.set(new Text(first), new Text(second), new Text(isAsc));
    }

    public void readFields(DataInput in) throws IOException
    {
        first.readFields(in);
        second.readFields(in);
        isAsc.readFields(in);

    }

    public void write(DataOutput out) throws IOException
    {
        first.write(out);
        second.write(out);
        isAsc.write(out);
    }

    @Override
    public int hashCode()
    {
        return first.hashCode() * 163 + second.hashCode();
    }

    @Override
    public String toString()
    {
        return first + "\t" + second;
    }

    public Text getFirst()
    {
        return first;
    }

    public Text getSecond()
    {
        return second;
    }

    public int compareTo(TextPairSort arg0)
    {
        TextPairSort tp = (TextPairSort) arg0;
        int cmp = first.compareTo(tp.first);
        if (cmp != 0)
        {
            return cmp;
        }
        if ("true".equals(isAsc.toString())) {
            return second.compareTo(tp.second);
        }
        return tp.second.compareTo(second);
    }

    public static class FirstComparator extends WritableComparator
    {
        private static final Text.Comparator TEXT_COMPARATOR = new Text.Comparator();

        protected FirstComparator()
        {
            super(TextPairSort.class);
        }

        @Override
        public int compare(byte[] b1, int s1, int l1,
                           byte[] b2, int s2, int l2)
        {
            try
            {
                int firstL1 = WritableUtils.decodeVIntSize(b1[s1]) + readVInt(b1, s1);
                int firstL2 = WritableUtils.decodeVIntSize(b2[s2]) + readVInt(b2, s2);
                return TEXT_COMPARATOR.compareBytes(b1, s1, firstL1, b2, s2, firstL2);
            } catch (IOException e)
            {
                e.printStackTrace();
            }
            return 0;
        }

        @Override
        public int compare(WritableComparable a, WritableComparable b)
        {
            if (a instanceof TextPairSort && b instanceof TextPairSort)
            {
                return ((TextPairSort) a).getFirst().compareTo(((TextPairSort) b).getFirst());
            }
            return super.compare(a, b);
        }

    }

    public static class FirstPartitioner extends Partitioner<TextPairSort, Text> {
        @Override
        public int getPartition(TextPairSort textPair, Text text, int numPartitions) {
            return (textPair.getFirst().hashCode() & Integer.MAX_VALUE) % numPartitions ;
        }
    }
}
