/*
 * 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.pig.data;

import java.io.DataInput;
import java.io.DataOutput;
import java.io.IOException;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.joda.time.DateTime;
import org.joda.time.DateTimeZone;

import org.apache.pig.backend.executionengine.ExecException;
import org.apache.pig.classification.InterfaceAudience;
import org.apache.pig.classification.InterfaceStability;
import org.apache.pig.data.utils.MethodHelper;
import org.apache.pig.data.utils.MethodHelper.NotImplemented;
import org.apache.pig.data.utils.SedesHelper;
import org.apache.pig.impl.logicalLayer.schema.Schema;
import org.apache.pig.impl.util.ObjectSerializer;

import com.google.common.collect.Lists;

/**
 * A SchemaTuple is a type aware tuple that is much faster and more memory efficient.
 * In our implementation, given a Schema, code generation is used to extend this class.
 * This class provides a broad range of functionality that minimizes the complexity of the
 * code that must be generated. The odd looking generic signature allows for certain
 * optimizations, such as "setSpecific(T t)", which allows us to do much faster sets and
 * comparisons when types match (since the code is generated, there is no other way to know).
 */
@InterfaceAudience.Public
@InterfaceStability.Unstable
public abstract class SchemaTuple<T extends SchemaTuple<T>> extends AbstractTuple implements TypeAwareTuple {
    private static final Log LOG = LogFactory.getLog(SchemaTuple.class);

    private static final long serialVersionUID = 1L;
    private static final int ONE_MINUTE = 60000;
    private static final BinInterSedes bis = new BinInterSedes();

    @NotImplemented
    @Override
    public void append(Object val) {
        throw MethodHelper.methodNotImplemented();
    }

    /**
     * This only accounts for the size of members (adjusting for word alignment). It also includes
     * the size of the object itself, since this never affects word boundaries.
     */
    @Override
    public long getMemorySize() {
        return 16 //Object header
             + getGeneratedCodeMemorySize();
    }

    protected abstract long getGeneratedCodeMemorySize();

    /**
     * This method will return the identifier that the generated code
     * was generated with. This is useful because when the classes
     * are resolved generically, this let's us know the identifier, which
     * is used when serlializing and deserializing tuples.
     * @return the identifire as Int.
     */
    public abstract int getSchemaTupleIdentifier();
    protected abstract int schemaSize();

    public String getSchemaString() {
        return getSchema().toString();
    }

    protected SchemaTuple<T> set(SchemaTuple<?> t, boolean checkType) throws ExecException {
        return generatedCodeSet(t, checkType);
    }

    protected abstract SchemaTuple<T> generatedCodeSet(SchemaTuple<?> t, boolean checkType) throws ExecException;

    protected SchemaTuple<T> setSpecific(T t) {
        return generatedCodeSetSpecific(t);
    }

    protected abstract SchemaTuple<T> generatedCodeSetSpecific(T t);

    public SchemaTuple<T> set(Tuple t) throws ExecException {
        return set(t, true);
    }

    @SuppressWarnings("unchecked") //this is ok because we only cast to T after checking
    protected SchemaTuple<T> set(Tuple t, boolean checkType) throws ExecException {
        if (checkType) {
            if (isSpecificSchemaTuple(t)) {
                return setSpecific((T)t);
            }

            if (t instanceof SchemaTuple<?>) {
                return set((SchemaTuple<?>)t, false);
        }
        }

        return set(t.getAll());
    }

    public SchemaTuple<T> set(SchemaTuple<?> t) throws ExecException {
        return set(t, true);
    }

    public SchemaTuple<T> set(List<Object> l) throws ExecException {
        if (l.size() != schemaSize()) {
            throw new ExecException("Given list of objects has improper number of fields ("+l.size()+" vs "+schemaSize()+")");
        }

        generatedCodeSetIterator(l.iterator());

        return this;
    }

    protected abstract void generatedCodeSetIterator(Iterator<Object> l) throws ExecException;

    protected void write(DataOutput out, boolean writeIdentifiers) throws IOException {
        if (writeIdentifiers) {
            int id = getSchemaTupleIdentifier();
            if (id < BinInterSedes.UNSIGNED_BYTE_MAX) {
                out.writeByte(BinInterSedes.SCHEMA_TUPLE_BYTE_INDEX);
                out.writeByte(id);
            } else if (id < BinInterSedes.UNSIGNED_SHORT_MAX) {
                out.writeByte(BinInterSedes.SCHEMA_TUPLE_SHORT_INDEX);
                out.writeShort(id);
            } else {
                out.writeByte(BinInterSedes.SCHEMA_TUPLE);
                out.writeInt(id);
            }
        }
        writeElements(out);
    }

    protected static void write(DataOutput out, DataBag v) throws IOException {
        bis.writeDatum(out, v, DataType.BAG);
    }

    protected static void write(DataOutput out, Map<String, Object> v) throws IOException {
        bis.writeDatum(out, v, DataType.MAP);
    }

    protected static void write(DataOutput out, int v) throws IOException {
        SedesHelper.Varint.writeSignedVarInt(v, out);
    }

    protected static void write(DataOutput out, long v) throws IOException {
        SedesHelper.Varint.writeSignedVarLong(v, out);
    }

    protected static void write(DataOutput out, float v) throws IOException {
        out.writeFloat(v);
    }

    protected static void write(DataOutput out, double v) throws IOException {
        out.writeDouble(v);
    }

    protected static void write(DataOutput out, DateTime v) throws IOException {
        out.writeLong(v.getMillis());
        out.writeShort(v.getZone().getOffset(v) / ONE_MINUTE);
    }

    protected static void write(DataOutput out, BigDecimal v) throws IOException {
        bis.writeDatum(out, v, DataType.BIGDECIMAL);
    }

    protected static void write(DataOutput out, BigInteger v) throws IOException {
        bis.writeDatum(out, v, DataType.BIGINTEGER);
    }

    protected static void write(DataOutput out, byte[] v) throws IOException {
        SedesHelper.writeBytes(out, v);
    }

    protected static void write(DataOutput out, String v) throws IOException {
        SedesHelper.writeChararray(out, v);
    }

    protected static void write(DataOutput out, SchemaTuple<?> t) throws IOException {
        t.writeElements(out);
    }

    protected static DataBag read(DataInput in, DataBag v) throws IOException {
        return (DataBag) bis.readDatum(in);
    }

    @SuppressWarnings("unchecked")
    protected static Map<String, Object> read(DataInput in, Map<String, Object> v) throws IOException {
        return (Map<String, Object>) bis.readDatum(in);
    }

    protected static int read(DataInput in, int v) throws IOException {
        return SedesHelper.Varint.readSignedVarInt(in);
    }

    protected static long read(DataInput in, long v) throws IOException {
        return SedesHelper.Varint.readSignedVarLong(in);
    }

    protected static float read(DataInput in, float v) throws IOException {
        return in.readFloat();
    }

    protected static double read(DataInput in, double v) throws IOException {
        return in.readDouble();
    }

    protected static DateTime read(DataInput in, DateTime v) throws IOException {
        return new DateTime(in.readLong(), DateTimeZone.forOffsetMillis(in.readShort() * ONE_MINUTE));
    }

    protected static BigDecimal read(DataInput in, BigDecimal v) throws IOException {
        return (BigDecimal) bis.readDatum(in);
    }

    protected static BigInteger read(DataInput in, BigInteger v) throws IOException {
        return (BigInteger) bis.readDatum(in);
    }

    protected static String read(DataInput in, String v) throws IOException {
        return SedesHelper.readChararray(in, in.readByte());
    }

    protected static byte[] read(DataInput in, byte[] v) throws IOException {
        return SedesHelper.readBytes(in, in.readByte());
    }

    @Override
    public void write(DataOutput out) throws IOException {
       write(out, true);
    }

    @Override
    public void reference(Tuple t) {
        try {
            set(t);
        } catch (ExecException e) {
            throw new RuntimeException("Failure to set given tuple: " + t, e);
        }
    }

    //TODO could generate a faster getAll in the code
    @Override
    public List<Object> getAll() {
        List<Object> l = Lists.newArrayListWithCapacity(size());
        for (int i = 0; i < size(); i++) {
            try {
                l.add(get(i));
            } catch (ExecException e) {
                throw new RuntimeException("Error getting index " + i + " from SchemaTuple", e);
            }
        }
        return l;
    }

    public abstract boolean isSpecificSchemaTuple(Object o);

    //TODO also need to implement the raw comparator
    @SuppressWarnings("unchecked")
    @Override
    public int compareTo(Object other) {
        if (isSpecificSchemaTuple(other)) {
            return compareToSpecific((T)other);
        }

        if (other instanceof SchemaTuple<?>) {
            return compareTo((SchemaTuple<?>)other, false);
        }

        if (other instanceof Tuple) {
            return compareTo((Tuple)other, false);
        }

        return DataType.compare(this, other);
    }

    public int compareTo(Tuple t) {
         return compareTo(t, true);
    }

    @SuppressWarnings("unchecked")
    protected int compareTo(Tuple t, boolean checkType) {
        if (checkType) {
            if (isSpecificSchemaTuple(t)) {
                return compareToSpecific((T)t);
            }

            if (t instanceof SchemaTuple<?>) {
                return compareTo((SchemaTuple<?>)t, false);
            }
        }

        int mySz = size();
        int tSz = t.size();

        if (tSz < mySz) {
            return 1;
        }

        if (tSz > mySz) {
            return -1;
        }

        for (int i = 0; i < mySz; i++) {
            try {
                int c = DataType.compare(get(i), t.get(i));

                if (c != 0) {
                    return c;
                }

            } catch (ExecException e) {
                throw new RuntimeException("Unable to compare tuples, t1 class = "
                        + getClass() + ", t2 class = " + t.getClass(), e);
            }
        }

        return 0;
    }

    public int compareTo(SchemaTuple<?> t) {
        return compareTo(t, true);
    }

    @SuppressWarnings("unchecked")
    protected int compareTo(SchemaTuple<?> t, boolean checkType) {
        if (checkType && isSpecificSchemaTuple(t)) {
            return compareToSpecific((T)t);
        }

        int i = compareSize(t);
        if (i != 0) {
            return i;
        }
        return generatedCodeCompareTo(t, checkType);
    }

    protected abstract int generatedCodeCompareTo(SchemaTuple<?> t, boolean checkType);

    protected int compareToSpecific(T t) {
        return generatedCodeCompareToSpecific(t);
    }

    protected abstract int generatedCodeCompareToSpecific(T t);

    @Override
    public boolean equals(Object other) {
        return (compareTo(other) == 0);
    }

    protected DataBag unbox(Object v, DataBag t) {
        return unbox((DataBag) v);
    }

    protected Map<String, Object> unbox(Object v, Map<String, Object> t) {
        return unbox((Map<String, Object>) v);
    }

    protected byte[] unbox(Object v, byte[] t) {
        return unbox((DataByteArray)v);
    }

    protected int unbox(Object v, int t) {
        return unbox((Integer)v);
    }

    protected long unbox(Object v, long t) {
        return unbox((Long)v);
    }

    protected float unbox(Object v, float t) {
        return unbox((Float)v);
    }

    protected double unbox(Object v, double t) {
        return unbox((Double)v);
    }

    protected boolean unbox(Object v, boolean t) {
        return unbox((Boolean)v);
    }

    protected DateTime unbox(Object v, DateTime t) {
        return (DateTime)v;
    }

    protected BigDecimal unbox(Object v, BigDecimal t) {
        return (BigDecimal)v;
    }

    protected BigInteger unbox(Object v, BigInteger t) {
        return (BigInteger)v;
    }

    protected String unbox(Object v, String t) {
        return (String)v;
    }

    protected Tuple unbox(Object v, Tuple t) {
        return (Tuple)v;
    }

    protected DataBag unbox(DataBag v) {
        return v;
    }

    protected Map<String, Object> unbox(Map<String, Object> v) {
        return v;
    }

    protected byte[] unbox(DataByteArray v) {
        if (v == null) {
            return null;
        }
        return v.get();
    }

    protected int unbox(Integer v) {
        return v.intValue();
    }

    protected long unbox(Long v) {
        return v.longValue();
    }

    protected float unbox(Float v) {
        return v.floatValue();
    }

    protected double unbox(Double v) {
        return v.doubleValue();
    }

    protected boolean unbox(Boolean v) {
        return v.booleanValue();
    }

    protected DateTime unbox(DateTime v) {
        return v;
    }

    protected DataBag box(DataBag v) {
        return v;
    }

    protected Map<String, Object> box(Map<String, Object> v) {
        return v;
    }

    protected DataByteArray box(byte[] v) {
        if (v == null) {
            return null;
        }
        return new DataByteArray(v);
    }

    protected String box(String v) {
        return v;
    }

    protected Tuple box(Tuple t) {
        return t;
    }

    protected Integer box(int v) {
        return new Integer(v);
    }

    protected Long box(long v) {
        return new Long(v);
    }

    protected Float box(float v) {
        return new Float(v);
    }

    protected Double box(double v) {
        return new Double(v);
    }

    protected Boolean box(boolean v) {
        return new Boolean(v);
    }

    protected DateTime box(DateTime v) {
        return v;
    }

    protected BigDecimal box(BigDecimal v) {
        return v;
    }

    protected BigInteger box(BigInteger v) {
        return v;
    }

    protected int hashCodePiece(int hash, int v, boolean isNull) {
        return isNull ? hash : 31 * hash + v;
    }

    protected int hashCodePiece(int hash, long v, boolean isNull) {
        return isNull ? hash : 31 * hash + (int)(v^(v>>>32));
    }

    protected int hashCodePiece(int hash, float v, boolean isNull) {
        return isNull ? hash : 31 * hash + Float.floatToIntBits(v);
    }

    protected int hashCodePiece(int hash, double v, boolean isNull) {
        long v2 = Double.doubleToLongBits(v);
        return isNull ? hash : 31 * hash + (int)(v2^(v2>>>32));
    }

    protected int hashCodePiece(int hash, boolean v, boolean isNull) {
        return isNull ? hash : 31 * hash + (v ? 1231 : 1237);
    }

    protected int hashCodePiece(int hash, DateTime v, boolean isNull) {
        return isNull ? hash : 31 * hash + v.hashCode();
    }

    protected int hashCodePiece(int hash, BigDecimal v, boolean isNull) {
        return isNull ? hash : 31 * hash + v.hashCode();
    }

    protected int hashCodePiece(int hash, BigInteger v, boolean isNull) {
        return isNull ? hash : 31 * hash + v.hashCode();
    }

    protected int hashCodePiece(int hash, byte[] v, boolean isNull) {
        return isNull ? hash : 31 * hash + DataByteArray.hashCode(v);
    }

    protected int hashCodePiece(int hash, String v, boolean isNull) {
        return isNull ? hash : 31 * hash + v.hashCode();
    }

    protected int hashCodePiece(int hash, Tuple v, boolean isNull) {
        return isNull ? hash : 31 * hash + v.hashCode();
    }

    protected int hashCodePiece(int hash, DataBag v, boolean isNull) {
        return isNull ? hash : 31 * hash + v.hashCode();
    }

    protected int hashCodePiece(int hash, Map<String, Object> v, boolean isNull) {
        return isNull ? hash : 31 * hash + v.hashCode();
    }

    @Override
    public int hashCode() {
        return generatedCodeHashCode();
    }

    protected abstract int generatedCodeHashCode();

    @Override
    public void set(int fieldNum, Object val) throws ExecException {
        generatedCodeSetField(fieldNum, val);
    }

    public abstract void generatedCodeSetField(int fieldNum, Object val) throws ExecException;

    @Override
    public Object get(int fieldNum) throws ExecException {
        return generatedCodeGetField(fieldNum);
    }

    public abstract Object generatedCodeGetField(int fieldNum) throws ExecException;

    @Override
    public boolean isNull(int fieldNum) throws ExecException {
        return isGeneratedCodeFieldNull(fieldNum);
    }

    public abstract boolean isGeneratedCodeFieldNull(int fieldNum) throws ExecException;

    @Override
    public byte getType(int fieldNum) throws ExecException {
        return getGeneratedCodeFieldType(fieldNum);
    }

    public abstract byte getGeneratedCodeFieldType(int fieldNum) throws ExecException;

    protected void setTypeAwareBase(int fieldNum, Object val, String type) throws ExecException {
        throw new ExecException("Given field " + fieldNum + " not a " + type + " field!");
    }

    protected Object getTypeAwareBase(int fieldNum, String type) throws ExecException {
        throw new ExecException("Given field " + fieldNum + " not a " + type + " field!");
    }

    @Override
    public void setInt(int fieldNum, int val) throws ExecException {
        generatedCodeSetInt(fieldNum, val);
    }

    protected abstract void generatedCodeSetInt(int fieldNum, int val) throws ExecException;

    @Override
    public void setLong(int fieldNum, long val) throws ExecException {
        generatedCodeSetLong(fieldNum, val);
    }

    protected abstract void generatedCodeSetLong(int fieldNum, long val) throws ExecException;

    @Override
    public void setFloat(int fieldNum, float val) throws ExecException {
        generatedCodeSetFloat(fieldNum, val);
    }

    protected abstract void generatedCodeSetFloat(int fieldNum, float val) throws ExecException;

    @Override
    public void setDouble(int fieldNum, double val) throws ExecException {
        generatedCodeSetDouble(fieldNum, val);
    }

    protected abstract void generatedCodeSetDouble(int fieldNum, double val) throws ExecException;

    @Override
    public void setBoolean(int fieldNum, boolean val) throws ExecException {
        generatedCodeSetBoolean(fieldNum, val);
    }

    protected abstract void generatedCodeSetBoolean(int fieldNum, boolean val) throws ExecException;

    @Override
    public void setDateTime(int fieldNum, DateTime val) throws ExecException {
         generatedCodeSetDateTime(fieldNum, val);
    }

    protected abstract void generatedCodeSetDateTime(int fieldNum, DateTime val) throws ExecException;

    @Override
    public void setBigDecimal(int fieldNum, BigDecimal val) throws ExecException {
         generatedCodeSetBigDecimal(fieldNum, val);
    }

    protected abstract void generatedCodeSetBigDecimal(int fieldNum, BigDecimal val) throws ExecException;

    @Override
    public void setBigInteger(int fieldNum, BigInteger val) throws ExecException {
         generatedCodeSetBigInteger(fieldNum, val);
    }

    protected abstract void generatedCodeSetBigInteger(int fieldNum, BigInteger val) throws ExecException;

    @Override
    public void setString(int fieldNum, String val) throws ExecException {
         generatedCodeSetString(fieldNum, val);
    }

    protected abstract void generatedCodeSetString(int fieldNum, String val) throws ExecException;

    @Override
    public void setTuple(int fieldNum, Tuple val) throws ExecException {
         generatedCodeSetTuple(fieldNum, val);
    }

    protected abstract void generatedCodeSetTuple(int fieldNum, Tuple val) throws ExecException;

    @Override
    public void setBytes(int fieldNum, byte[] val) throws ExecException {
        generatedCodeSetBytes(fieldNum, val);
    }

    protected abstract void generatedCodeSetBytes(int fieldNum, byte[] val) throws ExecException;

    @Override
    public void setDataBag(int fieldNum, DataBag val) throws ExecException {
        generatedCodeSetDataBag(fieldNum, val);
    }

    protected abstract void generatedCodeSetDataBag(int fieldNum, DataBag val) throws ExecException;

    @Override
    public void setMap(int fieldNum, Map<String, Object> val) throws ExecException {
        generatedCodeSetMap(fieldNum, val);
    }

    protected abstract void generatedCodeSetMap(int fieldNum, Map<String, Object> val) throws ExecException;

    private void errorIfNull(boolean isNull, String type) throws FieldIsNullException {
        if (isNull) {
            throw new FieldIsNullException("Desired field of type ["+type+"] was null!");
        }
    }

    protected int returnUnlessNull(boolean isNull, int val) throws FieldIsNullException {
        errorIfNull(isNull, "int");
        return val;
    }

    protected long returnUnlessNull(boolean isNull, long val) throws FieldIsNullException {
        errorIfNull(isNull, "long");
        return val;
    }

    protected float returnUnlessNull(boolean isNull, float val) throws FieldIsNullException {
        errorIfNull(isNull, "float");
        return val;
    }

    protected double returnUnlessNull(boolean isNull, double val) throws FieldIsNullException {
        errorIfNull(isNull, "double");
        return val;
    }

    protected boolean returnUnlessNull(boolean isNull, boolean val) throws FieldIsNullException {
        errorIfNull(isNull, "boolean");
        return val;
    }

    protected DateTime returnUnlessNull(boolean isNull, DateTime val) throws FieldIsNullException {
        errorIfNull(isNull, "DateTime");
        return val;
    }

    protected BigDecimal returnUnlessNull(boolean isNull, BigDecimal val) throws FieldIsNullException {
        errorIfNull(isNull, "BigDecimal");
        return val;
    }

    protected BigInteger returnUnlessNull(boolean isNull, BigInteger val) throws FieldIsNullException {
        errorIfNull(isNull, "BigInteger");
        return val;
    }

    protected Tuple returnUnlessNull(boolean isNull, Tuple val) throws FieldIsNullException {
        errorIfNull(isNull, "Tuple");
        return val;
    }

    protected String returnUnlessNull(boolean isNull, String val) throws FieldIsNullException {
        errorIfNull(isNull, "String");
        return val;
    }

    protected byte[] returnUnlessNull(boolean isNull, byte[] val) throws FieldIsNullException {
        errorIfNull(isNull, "byte");
        return val;
    }

    protected DataBag returnUnlessNull(boolean isNull, DataBag val) throws FieldIsNullException {
        errorIfNull(isNull, "DataBag");
        return val;
    }

    protected Map<String, Object> returnUnlessNull(boolean isNull, Map<String, Object> val) throws FieldIsNullException {
        errorIfNull(isNull, "Map<String,Object>");
        return val;
    }

    @Override
    public int getInt(int fieldNum) throws ExecException {
        return generatedCodeGetInt(fieldNum);
    }

    protected abstract int generatedCodeGetInt(int fieldNum) throws ExecException;

    public int unboxInt(Object val) {
        return ((Number)val).intValue();
    }

    @Override
    public long getLong(int fieldNum) throws ExecException {
        return generatedCodeGetLong(fieldNum);
    }

    protected abstract long generatedCodeGetLong(int fieldNum) throws ExecException;

    public long unboxLong(Object val) {
        return ((Number)val).longValue();
    }

    @Override
    public float getFloat(int fieldNum) throws ExecException {
        return generatedCodeGetFloat(fieldNum);
    }

    protected abstract float generatedCodeGetFloat(int fieldNum) throws ExecException;

    public float unboxFloat(Object val) {
        return ((Number)val).floatValue();
    }

    @Override
    public double getDouble(int fieldNum) throws ExecException {
        return generatedCodeGetDouble(fieldNum);
    }

    protected abstract double generatedCodeGetDouble(int fieldNum) throws ExecException;

    public double unboxDouble(Object val) {
        return ((Number)val).doubleValue();
    }

    @Override
    public boolean getBoolean(int fieldNum) throws ExecException {
        return generatedCodeGetBoolean(fieldNum);
    }

    protected abstract boolean generatedCodeGetBoolean(int fieldNum) throws ExecException;

    public boolean unboxBoolean(Object val) {
        return ((Boolean)val).booleanValue();
    }    

    @Override
    public DateTime getDateTime(int fieldNum) throws ExecException {
        return generatedCodeGetDateTime(fieldNum);
    }

    protected abstract DateTime generatedCodeGetDateTime(int fieldNum) throws ExecException;

    public DateTime unboxDateTime(Object val) {
        return (DateTime)val;
    }

    @Override
    public String getString(int fieldNum) throws ExecException {
        return generatedCodeGetString(fieldNum);
    }

    protected abstract String generatedCodeGetString(int fieldNum) throws ExecException;

    public String unboxString(Object val) {
        return (String)val;
    }

    @Override
    public byte[] getBytes(int fieldNum) throws ExecException {
        return generatedCodeGetBytes(fieldNum);
    }

    public byte[] unboxBytes(Object val) {
        DataByteArray dba = (DataByteArray)val;
        return val == null ? null : dba.get();
    }

    protected abstract byte[] generatedCodeGetBytes(int fieldNum) throws ExecException;

    @Override
    public Tuple getTuple(int fieldNum) throws ExecException {
        return generatedCodeGetTuple(fieldNum);
    }

    protected abstract Tuple generatedCodeGetTuple(int fieldNum) throws ExecException;

    protected Tuple unboxTuple(Object val) {
        return (Tuple)val;
    }

    @Override
    public DataBag getDataBag(int fieldNum) throws ExecException {
        return generatedCodeGetDataBag(fieldNum);
    }

    protected abstract DataBag generatedCodeGetDataBag(int fieldNum) throws ExecException;

    protected DataBag unboxDataBag(Object val) {
        return (DataBag)val;
    }

    @Override
    public Map<String, Object> getMap(int fieldNum) throws ExecException {
        return generatedCodeGetMap(fieldNum);
    }

    protected abstract Map<String, Object> generatedCodeGetMap(int fieldNum) throws ExecException;

    @SuppressWarnings("unchecked")
    protected Map<String, Object> unboxMap(Object val) {
        return (Map<String, Object>)val;
    }

    @Override
    public BigDecimal getBigDecimal(int fieldNum) throws ExecException {
        return generatedCodeGetBigDecimal(fieldNum);
    }

    protected abstract BigDecimal generatedCodeGetBigDecimal(int fieldNum)
            throws ExecException;

    public BigDecimal unboxBigDecimal(Object val) {
        return (BigDecimal) val;
    }

    @Override
    public BigInteger getBigInteger(int fieldNum) throws ExecException {
        return generatedCodeGetBigInteger(fieldNum);
    }

    protected abstract BigInteger generatedCodeGetBigInteger(int fieldNum)
            throws ExecException;

    public BigInteger unboxBigInteger(Object val) {
        return (BigInteger) val;
    }

    protected static Schema staticSchemaGen(String s) {
        try {
            if (s.equals("")) {
                LOG.warn("No Schema present in SchemaTuple generated class");
                return new Schema();
            }
            return (Schema) ObjectSerializer.deserialize(s);
        } catch (IOException e) {
            throw new RuntimeException("Unable to deserialize serialized Schema: " + s, e);
        }
    }

    public void setAndCatch(Tuple t) {
        try {
            set(t);
        } catch (ExecException e) {
            throw new RuntimeException("Unable to set position with Tuple: " + t, e);
        }
    }

    public void setAndCatch(SchemaTuple<?> t) {
        try {
            set(t);
        } catch (ExecException e) {
            throw new RuntimeException("Unable to set position with Tuple: " + t, e);
        }
    }

    /**
     * This method is responsible for writing everything contained by the Tuple.
     * Note that the base SchemaTuple class does not have an implementation (but is
     * not abstract) so that the generated code can call this method via super
     * without worrying about whether it is abstract or not, as there may be classes in
     * between in the inheritance tree (such as AppendableSchemaTuple).
     * @param out
     * @throws IOException
     */
    protected void writeElements(DataOutput out) throws IOException {
        boolean[] b = generatedCodeNullsArray();
        SedesHelper.writeBooleanArray(out, b);
        generatedCodeWriteElements(out);
    }

    protected abstract void generatedCodeWriteElements(DataOutput out) throws IOException;

    protected int compareSize(Tuple t) {
        return compare(size(), t.size());
    }

    protected int compareNull(boolean usNull, boolean themNull) {
        if (usNull && themNull) {
            return 2;
        } else if (themNull) {
            return 1;
        } else if (usNull) {
            return -1;
        }
        return 0;
    }

    protected int compareNull(boolean usNull, Tuple t, int pos) {
        boolean themNull;
        try {
            themNull = t.isNull(pos);
        } catch (ExecException e) {
            throw new RuntimeException("Unable to check if position " + pos + " is null in Tuple: " + t, e);
        }
        return compareNull(usNull, themNull);
    }

    protected int compareElementAtPos(int val, SchemaTuple<?> t, int pos) {
        int themVal;
        try {
            themVal = t.getInt(pos);
        } catch (ExecException e) {
            throw new RuntimeException("Unable to retrieve int field " + pos + " in given Tuple: " + t, e);
        }
        return compare(val, themVal);
    }

    protected int compare(boolean usNull, int usVal, boolean themNull, int themVal) {
        if (usNull && themNull) {
            return 0;
        } else if (themNull) {
            return 1;
        } else if (usNull) {
            return -1;
        }
        return compare(usVal, themVal);
    }

    protected int compare(int val, int themVal) {
        return val == themVal ? 0 : (val > themVal ? 1 : -1);
    }

    protected int compareWithElementAtPos(boolean isNull, int val, SchemaTuple<?> t, int pos) {
        int themVal;
        boolean themNull;
        try {
            themVal = t.getInt(pos);
            themNull = t.isNull(pos);
        } catch (ExecException e) {
            throw new RuntimeException("Unable to retrieve int field " + pos + " in given Tuple: " + t, e);
        }
        return compare(isNull, val, themNull, themVal);
    }

    protected int compare(boolean usNull, long usVal, boolean themNull, long themVal) {
        if (usNull && themNull) {
            return 0;
        } else if (themNull) {
            return 1;
        } else if (usNull) {
            return -1;
        }
        return compare(usVal, themVal);
    }

    protected int compare(long val, long themVal) {
        return val == themVal ? 0 : (val > themVal ? 1 : -1);
    }

    protected int compareWithElementAtPos(boolean isNull, long val, SchemaTuple<?> t, int pos) {
        long themVal;
        boolean themNull;
        try {
            themVal = t.getLong(pos);
            themNull = t.isNull(pos);
        } catch (ExecException e) {
            throw new RuntimeException("Unable to retrieve long field " + pos + " in given Tuple: " + t, e);
        }
        return compare(isNull, val, themNull, themVal);
    }

    protected int compare(boolean usNull, float usVal, boolean themNull, float themVal) {
        if (usNull && themNull) {
            return 0;
        } else if (themNull) {
            return 1;
        } else if (usNull) {
            return -1;
        }
        return compare(usVal, themVal);
    }

    public int compare(float val, float themVal) {
        return val == themVal ? 0 : (val > themVal ? 1 : -1);
    }

    protected int compareWithElementAtPos(boolean isNull, float val, SchemaTuple<?> t, int pos) {
        float themVal;
        boolean themNull;
        try {
            themVal = t.getFloat(pos);
            themNull = t.isNull(pos);
        } catch (ExecException e) {
            throw new RuntimeException("Unable to retrieve float field " + pos + " in given Tuple: " + t, e);
        }
        return compare(isNull, val, themNull, themVal);
    }

    protected int compare(boolean usNull, double usVal, boolean themNull, double themVal) {
        if (usNull && themNull) {
            return 0;
        } else if (themNull) {
            return 1;
        } else if (usNull) {
            return -1;
        }
        return compare(usVal, themVal);
    }

    protected int compare(double val, double themVal) {
        return val == themVal ? 0 : (val > themVal ? 1 : -1);
    }

    protected int compareWithElementAtPos(boolean isNull, double val, SchemaTuple<?> t, int pos) {
        double themVal;
        boolean themNull;
        try {
            themVal = t.getDouble(pos);
            themNull = t.isNull(pos);
        } catch (ExecException e) {
            throw new RuntimeException("Unable to retrieve double field " + pos + " in given Tuple: " + t, e);
        }
        return compare(isNull, val, themNull, themVal);
    }

    protected int compare(boolean usNull, boolean usVal, boolean themNull, boolean themVal) {
        if (usNull && themNull) {
            return 0;
        } else if (themNull) {
            return 1;
        } else if (usNull) {
            return -1;
        }
        return compare(usVal, themVal);
    }

    protected int compare(boolean val, boolean themVal) {
        if (val ^ themVal) {
            return val ? 1 : -1;
        }
        return 0;
    }

    protected int compareWithElementAtPos(boolean isNull, boolean val, SchemaTuple<?> t, int pos) {
        boolean themVal;
        boolean themNull;
        try {
            themVal = t.getBoolean(pos);
            themNull = t.isNull(pos);
        } catch (ExecException e) {
            throw new RuntimeException("Unable to retrieve boolean field " + pos + " in given Tuple: " + t, e);
        }
        return compare(isNull, val, themNull, themVal);
    }

    protected int compare(boolean usNull, byte[] usVal, boolean themNull, byte[] themVal) {
        if (usNull && themNull) {
            return 0;
        } else if (themNull) {
            return 1;
        } else if (usNull) {
            return -1;
        }
        return compare(usVal, themVal);
    }

    protected int compare(byte[] val, byte[] themVal) {
        return DataByteArray.compare(val, themVal);
    }

    protected int compareWithElementAtPos(boolean isNull, byte[] val, SchemaTuple<?> t, int pos) {
        byte[] themVal;
        boolean themNull;
        try {
            themVal = t.getBytes(pos);
            themNull = t.isNull(pos);
        } catch (ExecException e) {
            throw new RuntimeException("Unable to retrieve byte[] field " + pos + " in given Tuple: " + t, e);
        }
        return compare(isNull, val, themNull, themVal);
    }

    protected int compare(boolean usNull, DateTime usVal, boolean themNull, DateTime themVal) {
        if (usNull && themNull) {
            return 0;
        } else if (themNull) {
            return 1;
        } else if (usNull) {
            return -1;
        }
        return compare(usVal, themVal);
    }

    protected int compare(DateTime val, DateTime themVal) {
        return val.compareTo(themVal);
    }

    protected int compareWithElementAtPos(boolean isNull, DateTime val, SchemaTuple<?> t, int pos) {
        DateTime themVal;
        boolean themNull;
        try {
            themVal = t.getDateTime(pos);
            themNull = t.isNull(pos);
        } catch (ExecException e) {
            throw new RuntimeException("Unable to retrieve String field " + pos + " in given Tuple: " + t, e);
        }
        return compare(isNull, val, themNull, themVal);
    }

    protected int compare(boolean usNull, BigDecimal usVal, boolean themNull, BigDecimal themVal) {
        if (usNull && themNull) {
            return 0;
        } else if (themNull) {
            return 1;
        } else if (usNull) {
            return -1;
        }
        return compare(usVal, themVal);
    }

    protected int compare(BigDecimal val, BigDecimal themVal) {
        return val.compareTo(themVal);
    }

    protected int compareWithElementAtPos(boolean isNull, BigDecimal val, SchemaTuple<?> t, int pos) {
        BigDecimal themVal;
        boolean themNull;
        try {
            themVal = t.getBigDecimal(pos);
            themNull = t.isNull(pos);
        } catch (ExecException e) {
            throw new RuntimeException("Unable to retrieve String field " + pos + " in given Tuple: " + t, e);
        }
        return compare(isNull, val, themNull, themVal);
    }

    protected int compare(boolean usNull, BigInteger usVal, boolean themNull, BigInteger themVal) {
        if (usNull && themNull) {
            return 0;
        } else if (themNull) {
            return 1;
        } else if (usNull) {
            return -1;
        }
        return compare(usVal, themVal);
    }

    protected int compare(BigInteger val, BigInteger themVal) {
        return val.compareTo(themVal);
    }

    protected int compareWithElementAtPos(boolean isNull, BigInteger val, SchemaTuple<?> t, int pos) {
        BigInteger themVal;
        boolean themNull;
        try {
            themVal = t.getBigInteger(pos);
            themNull = t.isNull(pos);
        } catch (ExecException e) {
            throw new RuntimeException("Unable to retrieve String field " + pos + " in given Tuple: " + t, e);
        }
        return compare(isNull, val, themNull, themVal);
    }

    protected int compare(boolean usNull, String usVal, boolean themNull, String themVal) {
        if (usNull && themNull) {
            return 0;
        } else if (themNull) {
            return 1;
        } else if (usNull) {
            return -1;
        }
        return compare(usVal, themVal);
    }

    protected int compare(String val, String themVal) {
        return val.compareTo(themVal);
    }

    protected int compareWithElementAtPos(boolean isNull, String val, SchemaTuple<?> t, int pos) {
        String themVal;
        boolean themNull;
        try {
            themVal = t.getString(pos);
            themNull = t.isNull(pos);
        } catch (ExecException e) {
            throw new RuntimeException("Unable to retrieve String field " + pos + " in given Tuple: " + t, e);
        }
        return compare(isNull, val, themNull, themVal);
    }

    protected int compare(boolean usNull, DataBag usVal, boolean themNull, DataBag themVal) {
        if (usNull && themNull) {
            return 0;
        } else if (themNull) {
            return 1;
        } else if (usNull) {
            return -1;
        }
        return compare(usVal, themVal);
    }

    protected int compare(DataBag val, DataBag themVal) {
        return val.compareTo(themVal);
    }

    protected int compareWithElementAtPos(boolean isNull, DataBag val, SchemaTuple<?> t, int pos) {
        DataBag themVal;
        boolean themNull;
        try {
            themVal = t.getDataBag(pos);
            themNull = t.isNull(pos);
        } catch (ExecException e) {
            throw new RuntimeException("Unable to retrieve DataBag field " + pos + " in given Tuple: " + t, e);
        }
        return compare(isNull, val, themNull, themVal);
    }

    protected int compare(boolean usNull, Map<String, Object> usVal, boolean themNull, Map<String, Object> themVal) {
        if (usNull && themNull) {
            return 0;
        } else if (themNull) {
            return 1;
        } else if (usNull) {
            return -1;
        }
        return compare(usVal, themVal);
    }

    protected int compare(Map<String, Object> val, Map<String, Object> themVal) {
        return DataType.compare(val, themVal, DataType.MAP, DataType.MAP);
    }

    protected int compareWithElementAtPos(boolean isNull, Map<String, Object> val, SchemaTuple<?> t, int pos) {
        Map<String, Object> themVal;
        boolean themNull;
        try {
            themVal = t.getMap(pos);
            themNull = t.isNull(pos);
        } catch (ExecException e) {
            throw new RuntimeException("Unable to retrieve DataBag field " + pos + " in given Tuple: " + t, e);
        }
        return compare(isNull, val, themNull, themVal);
    }

    protected int compareWithElementAtPos(boolean isNull, SchemaTuple<?> val, SchemaTuple<?> t, int pos) {
        Object themVal;
        boolean themNull;
        try {
            themVal = t.get(pos);
            themNull = t.isNull(pos);
        } catch (ExecException e) {
            throw new RuntimeException("Unable to retrieve double field " + pos + " in given Tuple: " + t, e);
        }
        return compare(isNull, val, themNull, themVal);
    }

    protected int compare(boolean usNull, SchemaTuple<?> usVal, boolean themNull, Object themVal) {
        if (usNull && themNull) {
            return 0;
        } else if (themNull) {
            return 1;
        } else if (usNull) {
            return -1;
        }
        return usVal.compareTo(themVal);
    }

    /**
     * This is a mechanism which allows the SchemaTupleFactory to
     * get around having to use reflection. The generated code
     * will return a generator which will be created via reflection,
     * but after which can generate SchemaTuples at native speed.
     */
    public abstract SchemaTupleQuickGenerator<T> getQuickGenerator();

    public static abstract class SchemaTupleQuickGenerator<A> {
        public abstract A make();
    }

    public int size() {
        return generatedCodeSize();
    }

    protected abstract int generatedCodeSize();

    @Override
    public void readFields(DataInput in) throws IOException {
        boolean[] b = SedesHelper.readBooleanArray(in, schemaSize());
        generatedCodeReadFields(in, b);
    }

    protected abstract void generatedCodeReadFields(DataInput in, boolean[] nulls) throws IOException;

    protected abstract boolean[] generatedCodeNullsArray() throws IOException;
}
