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

import java.util.ArrayList;
import java.util.List;

import org.apache.hadoop.hive.serde2.objectinspector.ObjectInspector;
import org.apache.hadoop.hive.serde2.typeinfo.TypeInfo;
import org.apache.hadoop.hive.serde2.typeinfo.StructTypeInfo;
import org.apache.hadoop.hive.serde2.typeinfo.TypeInfoFactory;
import org.apache.hcatalog.data.schema.HCatSchema;
import org.apache.hcatalog.data.schema.HCatSchemaUtils;
import org.junit.Assert;
import org.junit.Test;

public class TestLazyHCatRecord {

    private final int INT_CONST = 789;
    private final long LONG_CONST = 5000000000L;
    private final double DOUBLE_CONST = 3.141592654;
    private final String STRING_CONST = "hello world";

    @Test
    public void testGet() throws Exception {
        HCatRecord r = new LazyHCatRecord(getHCatRecord(), getObjectInspector());
        Assert.assertEquals(INT_CONST, ((Integer) r.get(0)).intValue());
        Assert.assertEquals(LONG_CONST, ((Long) r.get(1)).longValue());
        Assert.assertEquals(DOUBLE_CONST, ((Double) r.get(2)).doubleValue(), 0);
        Assert.assertEquals(STRING_CONST, (String) r.get(3));
    }

    @Test
    public void testGetWithName() throws Exception {
        TypeInfo ti = getTypeInfo();
        HCatRecord r = new LazyHCatRecord(getHCatRecord(), getObjectInspector(ti));
        HCatSchema schema = HCatSchemaUtils.getHCatSchema(ti)
                                              .get(0).getStructSubSchema();
        Assert.assertEquals(INT_CONST, ((Integer) r.get("an_int", schema)).intValue());
        Assert.assertEquals(LONG_CONST, ((Long) r.get("a_long", schema)).longValue());
        Assert.assertEquals(DOUBLE_CONST, ((Double) r.get("a_double", schema)).doubleValue(), 0);
        Assert.assertEquals(STRING_CONST, (String) r.get("a_string", schema));
    }

    @Test
    public void testGetAll() throws Exception {
        HCatRecord r = new LazyHCatRecord(getHCatRecord(), getObjectInspector());
        List<Object> list = r.getAll();
        Assert.assertEquals(INT_CONST, ((Integer) list.get(0)).intValue());
        Assert.assertEquals(LONG_CONST, ((Long) list.get(1)).longValue());
        Assert.assertEquals(DOUBLE_CONST, ((Double) list.get(2)).doubleValue(), 0);
        Assert.assertEquals(STRING_CONST, (String) list.get(3));
    }

    @Test
    public void testSet() throws Exception {
        HCatRecord r = new LazyHCatRecord(getHCatRecord(), getObjectInspector());
        boolean sawException = false;
        try {
            r.set(3, "Mary had a little lamb");
        } catch (UnsupportedOperationException uoe) {
            sawException = true;
        }
        Assert.assertTrue(sawException);
    }

    @Test
    public void testSize() throws Exception {
        HCatRecord r = new LazyHCatRecord(getHCatRecord(), getObjectInspector());
        Assert.assertEquals(4, r.size());
    }

    @Test
    public void testReadFields() throws Exception {
        HCatRecord r = new LazyHCatRecord(getHCatRecord(), getObjectInspector());
        boolean sawException = false;
        try {
            r.readFields(null);
        } catch (UnsupportedOperationException uoe) {
            sawException = true;
        }
        Assert.assertTrue(sawException);
    }

    @Test
    public void testWrite() throws Exception {
        HCatRecord r = new LazyHCatRecord(getHCatRecord(), getObjectInspector());
        boolean sawException = false;
        try {
            r.write(null);
        } catch (UnsupportedOperationException uoe) {
            sawException = true;
        }
        Assert.assertTrue(sawException);
    }

    @Test
    public void testSetWithName() throws Exception {
        HCatRecord r = new LazyHCatRecord(getHCatRecord(), getObjectInspector());
        boolean sawException = false;
        try {
            r.set("fred", null, "bob");
        } catch (UnsupportedOperationException uoe) {
            sawException = true;
        }
        Assert.assertTrue(sawException);
    }

    @Test
    public void testRemove() throws Exception {
        HCatRecord r = new LazyHCatRecord(getHCatRecord(), getObjectInspector());
        boolean sawException = false;
        try {
            r.remove(0);
        } catch (UnsupportedOperationException uoe) {
            sawException = true;
        }
        Assert.assertTrue(sawException);
    }

    @Test
    public void testCopy() throws Exception {
        HCatRecord r = new LazyHCatRecord(getHCatRecord(), getObjectInspector());
        boolean sawException = false;
        try {
            r.copy(null);
        } catch (UnsupportedOperationException uoe) {
            sawException = true;
        }
        Assert.assertTrue(sawException);
    }

    @Test
    public void testGetWritable() throws Exception {
        HCatRecord r = new LazyHCatRecord(getHCatRecord(), getObjectInspector()).getWritable();
        Assert.assertEquals(INT_CONST, ((Integer) r.get(0)).intValue());
        Assert.assertEquals(LONG_CONST, ((Long) r.get(1)).longValue());
        Assert.assertEquals(DOUBLE_CONST, ((Double) r.get(2)).doubleValue(), 0);
        Assert.assertEquals(STRING_CONST, (String) r.get(3));
        Assert.assertEquals("org.apache.hcatalog.data.DefaultHCatRecord", r.getClass().getName());
    }

    private HCatRecord getHCatRecord() throws Exception {
        List<Object> rec_1 = new ArrayList<Object>(4);
        rec_1.add( new Integer(INT_CONST));
        rec_1.add( new Long(LONG_CONST));
        rec_1.add( new Double(DOUBLE_CONST));
        rec_1.add( new String(STRING_CONST));

        return new DefaultHCatRecord(rec_1);
    }

    private TypeInfo getTypeInfo() throws Exception {
        List<String> names = new ArrayList<String>(4);
        names.add("an_int");
        names.add("a_long");
        names.add("a_double");
        names.add("a_string");

        List<TypeInfo> tis = new ArrayList<TypeInfo>(4);
        tis.add(TypeInfoFactory.getPrimitiveTypeInfo("int"));
        tis.add(TypeInfoFactory.getPrimitiveTypeInfo("bigint"));
        tis.add(TypeInfoFactory.getPrimitiveTypeInfo("double"));
        tis.add(TypeInfoFactory.getPrimitiveTypeInfo("string"));

        return TypeInfoFactory.getStructTypeInfo(names, tis);
    }

    private ObjectInspector getObjectInspector(TypeInfo ti) throws Exception {
        return HCatRecordObjectInspectorFactory.getHCatRecordObjectInspector((StructTypeInfo)ti);
    }

    private ObjectInspector getObjectInspector() throws Exception {
        return HCatRecordObjectInspectorFactory.getHCatRecordObjectInspector(
            (StructTypeInfo)getTypeInfo());
    }
}
