/* 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.backend.hadoop.accumulo;

import java.io.ByteArrayInputStream;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.util.Map;

import org.apache.accumulo.core.Constants;
import org.apache.pig.LoadStoreCaster;
import org.apache.pig.ResourceSchema.ResourceFieldSchema;
import org.apache.pig.backend.executionengine.ExecException;
import org.apache.pig.data.DataBag;
import org.apache.pig.data.DataByteArray;
import org.apache.pig.data.Tuple;
import org.joda.time.DateTime;

import com.google.common.base.Preconditions;

/**
 * A LoadStoreCaster implementation which stores most type implementations as
 * bytes generated from the toString representation with a UTF8 Charset. Pulled
 * some implementations from the Accumulo Lexicoder implementations in 1.6.0.
 */
public class AccumuloBinaryConverter implements LoadStoreCaster {
    private static final int SIZE_OF_INT = Integer.SIZE / Byte.SIZE;
    private static final int SIZE_OF_LONG = Long.SIZE / Byte.SIZE;

    /**
     * NOT IMPLEMENTED
     */
    @Override
    public DataBag bytesToBag(byte[] b, ResourceFieldSchema fieldSchema)
            throws IOException {
        throw new ExecException("Can't generate DataBags from byte[]");
    }

    @Override
    public BigDecimal bytesToBigDecimal(byte[] b) throws IOException {
        throw new ExecException("Can't generate a BigInteger from byte[]");
    }

    @Override
    public BigInteger bytesToBigInteger(byte[] b) throws IOException {
        // Taken from Accumulo's BigIntegerLexicoder in 1.6.0
        DataInputStream dis = new DataInputStream(new ByteArrayInputStream(b));
        int len = dis.readInt();
        len = len ^ 0x80000000;
        len = Math.abs(len);

        byte[] bytes = new byte[len];
        dis.readFully(bytes);

        bytes[0] = (byte) (0x80 ^ bytes[0]);

        return new BigInteger(bytes);
    }

    @Override
    public Boolean bytesToBoolean(byte[] b) throws IOException {
        Preconditions.checkArgument(1 == b.length);
        return b[0] == (byte) 1;
    }

    @Override
    public String bytesToCharArray(byte[] b) throws IOException {
        return new String(b, Constants.UTF8);
    }

    /**
     * NOT IMPLEMENTED
     */
    @Override
    public DateTime bytesToDateTime(byte[] b) throws IOException {
        String s = new String(b, Constants.UTF8);
        return DateTime.parse(s);
    }

    @Override
    public Double bytesToDouble(byte[] b) throws IOException {
        return Double.longBitsToDouble(bytesToLong(b));
    }

    @Override
    public Float bytesToFloat(byte[] b) throws IOException {
        return Float.intBitsToFloat(bytesToInteger(b));
    }

    @Override
    public Integer bytesToInteger(byte[] b) throws IOException {
        Preconditions.checkArgument(b.length == SIZE_OF_INT);
        int n = 0;
        for (int i = 0; i < b.length; i++) {
            n <<= 8;
            n ^= b[i] & 0xFF;
        }
        return n;
    }

    @Override
    public Long bytesToLong(byte[] b) throws IOException {
        Preconditions.checkArgument(b.length == SIZE_OF_LONG);
        long l = 0;
        for (int i = 0; i < b.length; i++) {
            l <<= 8;
            l ^= b[i] & 0xFF;
        }
        return l;
    }

    /**
     * NOT IMPLEMENTED
     */
    @Override
    public Map<String, Object> bytesToMap(byte[] b,
            ResourceFieldSchema fieldSchema) throws IOException {
        throw new ExecException("Can't generate Map from byte[]");
    }

    /**
     * NOT IMPLEMENTED
     */
    @Override
    public Tuple bytesToTuple(byte[] b, ResourceFieldSchema fieldSchema)
            throws IOException {
        throw new ExecException("Can't generate a Tuple from byte[]");
    }

    /**
     * Not implemented!
     */
    @Override
    public byte[] toBytes(BigDecimal bd) throws IOException {
        throw new IOException("Can't generate bytes from BigDecimal");
    }

    @Override
    public byte[] toBytes(BigInteger bi) throws IOException {
        // Taken from Accumulo's BigIntegerLexicoder in 1.6.0
        byte[] bytes = bi.toByteArray();

        byte[] ret = new byte[4 + bytes.length];

        DataOutputStream dos = new DataOutputStream(
                new FixedByteArrayOutputStream(ret));

        // flip the sign bit
        bytes[0] = (byte) (0x80 ^ bytes[0]);

        int len = bytes.length;
        if (bi.signum() < 0)
            len = -len;

        len = len ^ 0x80000000;

        try {
            dos.writeInt(len);
            dos.write(bytes);
        } finally {
            dos.close();
        }

        return ret;
    }

    @Override
    public byte[] toBytes(Boolean b) throws IOException {
        return new byte[] { b ? (byte) 1 : (byte) 0 };
    }

    /**
     * NOT IMPLEMENTED
     */
    @Override
    public byte[] toBytes(DataBag bag) throws IOException {
        throw new ExecException("Cant' generate bytes from DataBag");
    }

    @Override
    public byte[] toBytes(DataByteArray a) throws IOException {
        return a.get();
    }

    @Override
    public byte[] toBytes(DateTime dt) throws IOException {
        return dt.toString().getBytes(Constants.UTF8);
    }

    @Override
    public byte[] toBytes(Double d) throws IOException {
        return toBytes(Double.doubleToRawLongBits(d));
    }

    @Override
    public byte[] toBytes(Float f) throws IOException {
        return toBytes(Float.floatToRawIntBits(f));
    }

    @Override
    public byte[] toBytes(Integer val) throws IOException {
        int intVal = val.intValue();
        byte[] b = new byte[4];
        for (int i = 3; i > 0; i--) {
            b[i] = (byte) intVal;
            intVal >>>= 8;
        }
        b[0] = (byte) intVal;
        return b;
    }

    @Override
    public byte[] toBytes(Long val) throws IOException {
        long longVal = val.longValue();
        byte[] b = new byte[8];
        for (int i = 7; i > 0; i--) {
            b[i] = (byte) longVal;
            longVal >>>= 8;
        }
        b[0] = (byte) longVal;
        return b;
    }

    /**
     * NOT IMPLEMENTED
     */
    @Override
    public byte[] toBytes(Map<String, Object> m) throws IOException {
        throw new IOException("Can't generate bytes from Map");
    }

    @Override
    public byte[] toBytes(String s) throws IOException {
        return s.getBytes(Constants.UTF8);
    }

    /**
     * NOT IMPLEMENTED
     */
    @Override
    public byte[] toBytes(Tuple t) throws IOException {
        throw new IOException("Can't generate bytes from Tuple");
    }
}
