/*
 * 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.vxquery.datamodel;

import org.apache.hyracks.data.std.api.IPointable;
import org.apache.hyracks.data.std.primitive.UTF8StringPointable;
import org.apache.hyracks.data.std.primitive.VoidPointable;
import org.apache.hyracks.data.std.util.ArrayBackedValueStorage;
import org.apache.vxquery.datamodel.accessors.SequencePointable;
import org.apache.vxquery.datamodel.accessors.TaggedValuePointable;
import org.apache.vxquery.datamodel.accessors.jsonitem.ObjectPointable;
import org.apache.vxquery.datamodel.builders.jsonitem.ObjectBuilder;
import org.apache.vxquery.datamodel.values.ValueTag;
import org.apache.vxquery.runtime.functions.util.FunctionHelper;
import org.junit.Assert;
import org.junit.Test;

import java.io.IOException;

public class ObjectByteTest extends AbstractPointableTest {
    private ArrayBackedValueStorage abvsResult = new ArrayBackedValueStorage();
    private ArrayBackedValueStorage abvsKeys = new ArrayBackedValueStorage();
    private ObjectBuilder ob = new ObjectBuilder();
    private TaggedValuePointable tvp = (TaggedValuePointable) TaggedValuePointable.FACTORY.createPointable();
    private UTF8StringPointable tvpKey1 = (UTF8StringPointable) UTF8StringPointable.FACTORY.createPointable();
    private TaggedValuePointable tvpValue1 = (TaggedValuePointable) TaggedValuePointable.FACTORY.createPointable();
    private UTF8StringPointable tvpKey2 = (UTF8StringPointable) UTF8StringPointable.FACTORY.createPointable();
    private TaggedValuePointable tvpValue2 = (TaggedValuePointable) TaggedValuePointable.FACTORY.createPointable();
    private UTF8StringPointable tvpKey3 = (UTF8StringPointable) UTF8StringPointable.FACTORY.createPointable();
    private TaggedValuePointable tvpValue3 = (TaggedValuePointable) TaggedValuePointable.FACTORY.createPointable();
    private SequencePointable sp = (SequencePointable) SequencePointable.FACTORY.createPointable();
    private ObjectPointable op = (ObjectPointable) ObjectPointable.FACTORY.createPointable();
    private IPointable vp = VoidPointable.FACTORY.createPointable();

    @Test
    public void testEmptyObject() {
        // Build test Object
        abvsResult.reset();
        try {
            ob.reset(abvsResult);
            ob.finish();
        } catch (IOException e) {
            Assert.fail("Test failed to write the Object pointable.");
        }
        tvp.set(abvsResult);

        // Check results.
        if (tvp.getTag() != ValueTag.OBJECT_TAG) {
            Assert.fail("Type tag is incorrect. Expected: " + ValueTag.OBJECT_TAG + " Got: " + tvp.getTag());
        }
        tvp.getValue(op);
        if (op.getEntryCount() != 0) {
            Assert.fail("Object size is incorrect. Expected: 0 Got: " + op.getEntryCount());
        }
    }

    @Test
    public void testSingleItemObject() {
        // Build test Object
        abvsResult.reset();
        try {
            ob.reset(abvsResult);
            getTaggedValuePointable("id", false, tvpKey1);
            getTaggedValuePointable(1, tvpValue1);
            ob.addItem(tvpKey1, tvpValue1);
            ob.finish();
        } catch (IOException e) {
            Assert.fail("Test failed to write the object pointable.");
        }
        tvp.set(abvsResult);

        // Check results.
        if (tvp.getTag() != ValueTag.OBJECT_TAG) {
            Assert.fail("Type tag is incorrect. Expected: " + ValueTag.OBJECT_TAG + " Got: " + tvp.getTag());
        }

        tvp.getValue(op);
        if (op.getEntryCount() != 1) {
            Assert.fail("Object size is incorrect. Expected: 1 Got: " + op.getEntryCount());
        }
        try {
            op.getKeys(abvsKeys);
            tvp.set(abvsKeys);
        } catch (IOException e) {
            Assert.fail("Test failed to write the object pointable.");
        }
        if (tvp.getTag() != ValueTag.XS_STRING_TAG) {
            Assert.fail("Type tag is incorrect. Expected: " + ValueTag.XS_STRING_TAG + " Got: " + tvp.getTag());
        }
        if (!compareKeys(tvp, tvpKey1)) {
            Assert.fail("Key is incorrect. Expected: id");
        }

        if (!op.getValue(tvpKey1, tvp)) {
            Assert.fail("Value not found for the given key:id");
        }
        if (!FunctionHelper.arraysEqual(tvp, tvpValue1)) {
            Assert.fail("Value is incorrect for the given key. Expected: 1 with valuetag: " + ValueTag.XS_INT_TAG
                    + " Got valuetag: " + tvp.getTag());
        }
    }

    @Test
    public void testManyItemObject() {
        // Build test object
        try {
            // Add three items
            ob.reset(abvsResult);
            getTaggedValuePointable("name", false, tvpKey1);
            getTaggedValuePointable("A green door", tvpValue1);
            ob.addItem(tvpKey1, tvpValue1);
            getTaggedValuePointable("price", false, tvpKey2);
            getTaggedValuePointable(12.5, tvpValue2);
            ob.addItem(tvpKey2, tvpValue2);
            getTaggedValuePointable("properties", false, tvpKey3);
            getTaggedValuePointable(100L, tvpValue3);
            ob.addItem(tvpKey3, tvpValue3);
            ob.finish();
        } catch (IOException e) {
            Assert.fail("Test failed to write the object pointable.");
        }
        tvp.set(abvsResult);

        // Check results.
        if (tvp.getTag() != ValueTag.OBJECT_TAG) {
            Assert.fail("Type tag is incorrect. Expected: " + ValueTag.OBJECT_TAG + " Got: " + tvp.getTag());
        }
        tvp.getValue(op);
        if (op.getEntryCount() != 3) {
            Assert.fail("Object size is incorrect. Expected: 3 Got: " + op.getEntryCount());
        }

        //Test keys
        try {
            op.getKeys(abvsKeys);
            tvp.set(abvsKeys);
        } catch (IOException e) {
            Assert.fail("Test failed to write the object pointable.");
        }

        if (tvp.getTag() != ValueTag.SEQUENCE_TAG) {
            Assert.fail("Tag type is incorrect. Expected: " + ValueTag.SEQUENCE_TAG + " Got: " + tvp.getTag());
        }
        tvp.getValue(sp);
        if (sp.getEntryCount() != 3) {
            Assert.fail("Object size is incorrect. Expected: 3 Got: " + sp.getEntryCount());
        }
        sp.getEntry(0, tvp);
        if (tvp.getTag() != ValueTag.XS_STRING_TAG) {
            Assert.fail("Type tag is incorrect. Expected: " + ValueTag.XS_STRING_TAG + " Got: " + tvp.getTag());
        }
        if (!compareKeys(tvp, tvpKey1)) {
            Assert.fail("Object key one is incorrect. Expected: name");
        }
        sp.getEntry(1, tvp);
        if (tvp.getTag() != ValueTag.XS_STRING_TAG) {
            Assert.fail("Type tag is incorrect. Expected: " + ValueTag.XS_STRING_TAG + " Got: " + tvp.getTag());
        }
        if (!compareKeys(tvp, tvpKey2)) {
            Assert.fail("Object key two is incorrect. Expected: price");
        }
        sp.getEntry(2, tvp);
        if (tvp.getTag() != ValueTag.XS_STRING_TAG) {
            Assert.fail("Type tag is incorrect. Expected: " + ValueTag.XS_STRING_TAG + " Got: " + tvp.getTag());
        }
        if (!compareKeys(tvp, tvpKey3)) {
            Assert.fail("Object key three is incorrect. Expected: properties");
        }

        //Test values
        if (!op.getValue(tvpKey1, tvp)) {
            Assert.fail("Value not found for the given key: name");
        }
        if (!FunctionHelper.arraysEqual(tvp, tvpValue1)) {
            Assert.fail("Value is incorrect for the given key. Expected: A green door with valuetag: "
                    + ValueTag.XS_STRING_TAG + " Got valuetag: " + tvp.getTag());
        }

        if (!op.getValue(tvpKey2, tvp)) {
            Assert.fail("Value not found for the given key: price");
        }
        if (!FunctionHelper.arraysEqual(tvp, tvpValue2)) {
            Assert.fail("Value is incorrect for the given key. Expected: 12.5 with valuetag: " + ValueTag.XS_DOUBLE_TAG
                    + " Got valuetag: " + tvp.getTag());
        }

        if (!op.getValue(tvpKey3, tvp)) {
            Assert.fail("Value not found for the given key: properties");
        }
        if (!FunctionHelper.arraysEqual(tvp, tvpValue3)) {
            Assert.fail("Value is incorrect for the given key. Expected: 100 with valuetag: " + ValueTag.XS_LONG_TAG
                    + " Got valuetag: " + tvp.getTag());
        }
    }

    @Test
    public void testItemNotExistObject() {
        // Build empty test Object
        abvsResult.reset();
        try {
            ob.reset(abvsResult);
            ob.finish();
        } catch (IOException e) {
            Assert.fail("Test failed to write the Object pointable.");
        }
        tvp.set(abvsResult);
        tvp.getValue(op);
        try {
            getTaggedValuePointable("key", false, tvpKey1);
            if (op.getValue(tvpKey1, tvp)) {
                Assert.fail("key not in object. Expected: false Got: true");
            }
        } catch (IOException e) {
            Assert.fail("Test failed to write the object pointable.");
        }

        // Build test object
        try {
            // Add two items
            abvsResult.reset();
            ob.reset(abvsResult);
            getTaggedValuePointable("name", false, tvpKey1);
            getTaggedValuePointable("A green door", tvpValue1);
            ob.addItem(tvpKey1, tvpValue1);
            getTaggedValuePointable("price", false, tvpKey2);
            getTaggedValuePointable(12.5, tvpValue2);
            ob.addItem(tvpKey2, tvpValue2);
            ob.finish();
        } catch (IOException e) {
            Assert.fail("Test failed to write the object pointable.");
        }

        tvp.set(abvsResult);
        tvp.getValue(op);
        try {
            getTaggedValuePointable("key", false, tvpKey3);
            if (op.getValue(tvpKey3, tvp)) {
                Assert.fail("key not in object. Expected: false Got: true");
            }

            if (!op.getValue(tvpKey1, tvp)) {
                Assert.fail("key in object. Expected: true Got: false");
            }
        } catch (IOException e) {
            Assert.fail("Test failed to write the object pointable.");
        }
    }

    private boolean compareKeys(TaggedValuePointable tvp1, IPointable tvp2) {
        tvp1.getValue(vp);
        return FunctionHelper.arraysEqual(vp.getByteArray(), vp.getStartOffset(), vp.getLength(), tvp2.getByteArray(),
                tvp2.getStartOffset(), tvp2.getLength());
    }
}
