/**
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.apache.mrql;

import java.io.*;
import org.apache.hadoop.io.*;
import org.apache.hadoop.fs.*;


/** a container for Tuples */
final public class Tuple extends MRData {
    private final static long serialVersionUID = 723385754575L;

    MRData[] tuple;

    public Tuple () { tuple = new MRData[0]; }

    public Tuple ( int size ) {
        tuple = new MRData[size];
    }

    public Tuple ( final MRData ...as ) {
        tuple = as;
    }

    /** the number of elements in the tuple */
    public short size () { return (short)tuple.length; }

    public void materializeAll () {
        for (MRData e: tuple)
            e.materializeAll();
    };

    /** the i'th element of the tuple */
    public MRData get ( int i ) {
        return tuple[i];
    }

    /** the first element of the tuple */
    public MRData first () { return tuple[0]; }

    /** the second element of the tuple */
    public MRData second () { return tuple[1]; }

    /** replace the i'th element of a tuple with new data and return a new value */
    public MRData set ( int i, MRData data, MRData ret ) {
        tuple[i] = data;
        return ret;
    }

    /** replace the i'th element of a tuple with new data */
    public Tuple set ( int i, MRData data ) {
        tuple[i] = data;
        return this;
    }

    final public void write ( DataOutput out ) throws IOException {
        if (tuple.length == 0)
            out.writeByte(MRContainer.NULL);
        else if (tuple.length == 2) {
            out.writeByte(MRContainer.PAIR);
            tuple[0].write(out);
            tuple[1].write(out);
        } else if (tuple.length == 3) {
            out.writeByte(MRContainer.TRIPLE);
            tuple[0].write(out);
            tuple[1].write(out);
            tuple[2].write(out);
        } else {
            out.writeByte(MRContainer.TUPLE);
            WritableUtils.writeVInt(out,tuple.length);
            for (short i = 0; i < tuple.length; i++)
                tuple[i].write(out);
        }
    }

    final public static Tuple read ( DataInput in ) throws IOException {
        int n = WritableUtils.readVInt(in);
        Tuple t = new Tuple(n);
        for ( short i = 0; i < n; i++ )
            t.tuple[i] = MRContainer.read(in);
        return t;
    }

    final public static Tuple read2 ( DataInput in ) throws IOException {
        return new Tuple(MRContainer.read(in),MRContainer.read(in));
    }

    final public static Tuple read3 ( DataInput in ) throws IOException {
        return new Tuple(MRContainer.read(in),MRContainer.read(in),MRContainer.read(in));
    }

    public void readFields ( DataInput in ) throws IOException {
        int n = WritableUtils.readVInt(in);
        tuple = new Tuple[n];
        for ( short i = 0; i < n; i++ )
            tuple[i] = MRContainer.read(in);
    }

    public int compareTo ( MRData x ) {
        assert(x instanceof Tuple);
        Tuple t = (Tuple) x;
        for ( short i = 0; i < tuple.length && i < t.tuple.length; i++ ) {
            int c = get(i).compareTo(t.get(i));
            if (c < 0)
                return -1;
            else if (c > 0)
                return 1;
        };
        if (tuple.length > t.tuple.length)
            return 1;
        else if (tuple.length < t.tuple.length)
            return -1;
        else return 0;
    }

    final public static int compare ( byte[] x, int xs, int xl, byte[] y, int ys, int yl, int[] size ) {
        try {
            int n = WritableComparator.readVInt(x,xs);
            int s = WritableUtils.decodeVIntSize(x[xs]);
            for ( short i = 0; i < n; i++ ) {
                int k = MRContainer.compare(x,xs+s,xl-s,y,ys+s,yl-s,size);
                if (k != 0)
                    return k;
                s += size[0];
            };
            size[0] = s+1;
            return 0;
        } catch (IOException e) {
            throw new Error(e);
        }
    }

    final public static int compare2 ( byte[] x, int xs, int xl, byte[] y, int ys, int yl, int[] size ) {
        int k = MRContainer.compare(x,xs,xl,y,ys,yl,size);
        if (k != 0)
            return k;
        int s = size[0];
        k = MRContainer.compare(x,xs+s,xl-s,y,ys+s,yl-s,size);
        if (k != 0)
            return k;
        size[0] += s+1;
        return 0;
    }

    final public static int compare3 ( byte[] x, int xs, int xl, byte[] y, int ys, int yl, int[] size ) {
        int k = MRContainer.compare(x,xs,xl,y,ys,yl,size);
        if (k != 0)
            return k;
        int s = size[0];
        k = MRContainer.compare(x,xs+s,xl-s,y,ys+s,yl-s,size);
        if (k != 0)
            return k;
        s += size[0];
        k = MRContainer.compare(x,xs+s,xl-s,y,ys+s,yl-s,size);
        if (k != 0)
            return k;
        size[0] += s+1;
        return 0;
    }

    public boolean equals ( Object x ) {
        if (!(x instanceof Tuple))
            return false;
        Tuple xt = (Tuple) x;
        if (xt.tuple.length != tuple.length)
            return false;
        for ( short i = 0; i < tuple.length; i++ )
            if (!xt.get(i).equals(get(i)))
                return false;
        return true;
    }

    public int hashCode () {
        int h = 127;
        for ( short i = 1; i < tuple.length; i++ )
            h ^= get(i).hashCode();
        return Math.abs(h);
    }

    public String toString () {
        if (size() == 0)
            return "()";
        String s = "("+get((short)0);
        for ( short i = 1; i < tuple.length; i++ )
            s += ","+get(i);
        return s+")";
    }
}
