/*
 * 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.
 */

#include <boost/test/unit_test.hpp>

#include "ignite/impl/interop/interop.h"
#include "ignite/impl/binary/binary_reader_impl.h"
#include "ignite/impl/binary/binary_writer_impl.h"

#include "ignite/binary_test_defs.h"

using namespace ignite;
using namespace ignite::impl::interop;
using namespace ignite::impl::binary;
using namespace ignite::binary;
using namespace ignite_test::core::binary;

/*
 * Check primitive value serialization-deserialization.
 */
template<typename T>
void CheckRawPrimitive(T writeVal) 
{
    InteropUnpooledMemory mem(1024);

    InteropOutputStream out(&mem); 
    BinaryWriterImpl writeSes(&out, NULL);
    writeSes.WriteTopObject<T>(writeVal);
    out.Synchronize();

    InteropInputStream in(&mem); 
    BinaryReaderImpl reader(&in);
    T readVal = reader.ReadTopObject<T>();

    BOOST_REQUIRE(readVal == writeVal);
}

BOOST_AUTO_TEST_SUITE(BinarySessionTestSuite)

BOOST_AUTO_TEST_CASE(TestByte)
{
    CheckRawPrimitive<int8_t>(-128);
    CheckRawPrimitive<int8_t>(-1);
    CheckRawPrimitive<int8_t>(0);
    CheckRawPrimitive<int8_t>(1);
    CheckRawPrimitive<int8_t>(127);
}

BOOST_AUTO_TEST_CASE(TestBool)
{
    CheckRawPrimitive<bool>(true);
    CheckRawPrimitive<bool>(false);
}

BOOST_AUTO_TEST_CASE(TestShort)
{
    //CheckRawPrimitive<int16_t>(std::numeric_limits<int16_t>::min()); 
    CheckRawPrimitive<int16_t>(-1);
    CheckRawPrimitive<int16_t>(0);
    CheckRawPrimitive<int16_t>(1);
    //CheckRawPrimitive<int16_t>(std::numeric_limits<int16_t>::max());
}

BOOST_AUTO_TEST_CASE(TestChar)
{
    //CheckRawPrimitive<uint16_t>(std::numeric_limits<uint16_t>::min());
    CheckRawPrimitive<uint16_t>(1);
    //CheckRawPrimitive<uint16_t>(std::numeric_limits<uint16_t>::max());
}

BOOST_AUTO_TEST_CASE(TestInt)
{
    //CheckRawPrimitive<int32_t>(std::numeric_limits<int32_t>::min());
    CheckRawPrimitive<int32_t>(-1);
    CheckRawPrimitive<int32_t>(0);
    CheckRawPrimitive<int32_t>(1);
    //CheckRawPrimitive<int32_t>(std::numeric_limits<int32_t>::max());
}

BOOST_AUTO_TEST_CASE(TestLong)
{
    //CheckRawPrimitive<int64_t>(std::numeric_limits<int64_t>::min());
    CheckRawPrimitive<int64_t>(-1);
    CheckRawPrimitive<int64_t>(0);
    CheckRawPrimitive<int64_t>(1);
    //CheckRawPrimitive<int64_t>(std::numeric_limits<int64_t>::max());
}

BOOST_AUTO_TEST_CASE(TestFloat)
{
    CheckRawPrimitive<float>(-1.1f);
    CheckRawPrimitive<float>(0);
    CheckRawPrimitive<float>(1.1f);
}

BOOST_AUTO_TEST_CASE(TestDouble)
{
    CheckRawPrimitive<double>(-1.1);
    CheckRawPrimitive<double>(0);
    CheckRawPrimitive<double>(1.1);
}

BOOST_AUTO_TEST_CASE(TestGuid)
{
    Guid writeVal = Guid(1, 1);

    InteropUnpooledMemory mem(1024);

    InteropOutputStream out(&mem);
    BinaryWriterImpl writeSes(&out, NULL);
    writeSes.WriteTopObject<Guid>(writeVal);
    out.Synchronize();

    InteropInputStream in(&mem);
    BinaryReaderImpl reader(&in);
    Guid readVal = reader.ReadTopObject<Guid>();

    BOOST_REQUIRE(readVal.GetMostSignificantBits() == writeVal.GetMostSignificantBits());
    BOOST_REQUIRE(readVal.GetLeastSignificantBits() == writeVal.GetLeastSignificantBits());    
}

BOOST_AUTO_TEST_CASE(TestDate)
{
    Date writeVal = Date(42);

    InteropUnpooledMemory mem(1024);

    InteropOutputStream out(&mem);
    BinaryWriterImpl writeSes(&out, NULL);
    writeSes.WriteTopObject<Date>(writeVal);
    out.Synchronize();

    InteropInputStream in(&mem);
    BinaryReaderImpl reader(&in);
    Date readVal = reader.ReadTopObject<Date>();

    BOOST_REQUIRE(readVal == writeVal);
}

BOOST_AUTO_TEST_CASE(TestTime)
{
    Time writeVal = Time(42);

    InteropUnpooledMemory mem(1024);

    InteropOutputStream out(&mem);
    BinaryWriterImpl writeSes(&out, NULL);
    writeSes.WriteTopObject<Time>(writeVal);
    out.Synchronize();

    InteropInputStream in(&mem);
    BinaryReaderImpl reader(&in);
    Time readVal = reader.ReadTopObject<Time>();

    BOOST_REQUIRE(readVal == writeVal);
}

BOOST_AUTO_TEST_CASE(TestTimestamp)
{
    Timestamp writeVal = Timestamp(77);

    InteropUnpooledMemory mem(1024);

    InteropOutputStream out(&mem);
    BinaryWriterImpl writeSes(&out, NULL);
    writeSes.WriteTopObject<Timestamp>(writeVal);
    out.Synchronize();

    InteropInputStream in(&mem);
    BinaryReaderImpl reader(&in);
    Timestamp readVal = reader.ReadTopObject<Timestamp>();

    BOOST_CHECK(readVal == writeVal);
    BOOST_CHECK_EQUAL(readVal.GetMilliseconds(), writeVal.GetMilliseconds());
    BOOST_CHECK_EQUAL(readVal.GetSecondFraction(), writeVal.GetSecondFraction());
}

BOOST_AUTO_TEST_CASE(TestString)
{
    std::string writeVal = "MyString";

    InteropUnpooledMemory mem(1024);

    InteropOutputStream out(&mem);
    BinaryWriterImpl writeSes(&out, NULL);
    writeSes.WriteTopObject<std::string>(writeVal);
    out.Synchronize();

    InteropInputStream in(&mem);
    BinaryReaderImpl reader(&in);
    std::string readVal = reader.ReadTopObject<std::string>();

    BOOST_REQUIRE(readVal.compare(writeVal) == 0);
}

BOOST_AUTO_TEST_CASE(TestObject)
{
    InteropUnpooledMemory mem(1024);
    
    InteropOutputStream out(&mem);
    BinaryWriterImpl writer(&out, NULL);

    InteropInputStream in(&mem);
    BinaryReaderImpl reader(&in);

    // 1. Test null object.
    BinaryInner writeVal(0);
    
    writer.WriteTopObject<BinaryInner>(writeVal);
    out.Synchronize();
    
    in.Synchronize();
    BinaryInner readVal = reader.ReadTopObject<BinaryInner>();

    BOOST_REQUIRE(readVal.GetValue() == 0);

    // 2. Test non-null object.
    out.Position(0);
    in.Position(0);

    writeVal = BinaryInner(1);

    writer.WriteTopObject<BinaryInner>(writeVal);
    out.Synchronize();

    in.Synchronize();
    readVal = reader.ReadTopObject<BinaryInner>();

    BOOST_REQUIRE(readVal.GetValue() == 1);
}

BOOST_AUTO_TEST_CASE(TestObjectWithRawFields)
{
    InteropUnpooledMemory mem(1024);

    InteropOutputStream out(&mem);
    BinaryWriterImpl writer(&out, NULL);

    InteropInputStream in(&mem);
    BinaryReaderImpl reader(&in);

    out.Position(0);
    in.Position(0);

    BinaryFields writeVal = BinaryFields(1, 2, 3, 4);

    writer.WriteTopObject<BinaryFields>(writeVal);
    out.Synchronize();

    in.Synchronize();
    BinaryFields readVal = reader.ReadTopObject<BinaryFields>();

    BOOST_REQUIRE(readVal.val1 == 1);
    BOOST_REQUIRE(readVal.val2 == 2);
    BOOST_REQUIRE(readVal.rawVal1 == 3);
    BOOST_REQUIRE(readVal.rawVal2 == 4);
}

BOOST_AUTO_TEST_CASE(TestPointer)
{
    InteropUnpooledMemory mem(1024);

    InteropOutputStream out(&mem);
    BinaryWriterImpl writer(&out, NULL);

    InteropInputStream in(&mem);
    BinaryReaderImpl reader(&in);

    // 1. Test null object.
    writer.WriteTopObject<BinaryInner*>(NULL);
    out.Synchronize();

    in.Synchronize();
    BinaryInner* readVal = reader.ReadTopObject<BinaryInner*>();

    BOOST_REQUIRE(readVal == NULL);

    // 2. Test non-null object.
    out.Position(0);
    in.Position(0);

    BinaryInner writeVal = BinaryInner(1);

    writer.WriteTopObject<BinaryInner*>(&writeVal);
    out.Synchronize();

    in.Synchronize();
    readVal = reader.ReadTopObject<BinaryInner*>();

    BOOST_REQUIRE(readVal->GetValue() == 1);

    delete readVal;
}

BOOST_AUTO_TEST_SUITE_END()
