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

using System;
using System.IO;
using Xunit;
using PdxTests;
using System.Collections;
using System.Collections.Generic;
using Xunit.Abstractions;

namespace Apache.Geode.Client.IntegrationTests
{
    public class Order : IDataSerializable
    {
        public int OrderId { get; set; }
        public string Name { get; set; }
        public short Quantity { get; set; }

        // A default constructor is required for deserialization
        public Order() { }

        public Order(int orderId, string name, short quantity)
        {
            OrderId = orderId;
            Name = name;
            Quantity = quantity;
        }

        public override string ToString()
        {
            return string.Format("Order: [{0}, {1}, {2}]", OrderId, Name, Quantity);
        }

        public void ToData(DataOutput output)
        {
            output.WriteInt32(OrderId);
            output.WriteUTF(Name);
            output.WriteInt16(Quantity);
        }

        public void FromData(DataInput input)
        {
            OrderId = input.ReadInt32();
            Name = input.ReadUTF();
            Quantity = input.ReadInt16();
        }

        public ulong ObjectSize
        {
            get { return 0; }
        }

        public static ISerializable CreateDeserializable()
        {
            return new Order();
        }

    }

    public struct CData
    {
        #region Private members

        private Int32 m_first;
        private Int64 m_second;

        #endregion

        #region Public accessors

        public Int32 First
        {
            get
            {
                return m_first;
            }
            set
            {
                m_first = value;
            }
        }

        public Int64 Second
        {
            get
            {
                return m_second;
            }
            set
            {
                m_second = value;
            }
        }

        #endregion

        public CData(Int32 first, Int64 second)
        {
            m_first = first;
            m_second = second;
        }

        public static bool operator ==(CData obj1, CData obj2)
        {
            return ((obj1.m_first == obj2.m_first) && (obj1.m_second == obj2.m_second));
        }

        public static bool operator !=(CData obj1, CData obj2)
        {
            return ((obj1.m_first != obj2.m_first) || (obj1.m_second != obj2.m_second));
        }

        public override bool Equals(object obj)
        {
            if (obj is CData)
            {
                CData otherObj = (CData)obj;
                return ((m_first == otherObj.m_first) && (m_second == otherObj.m_second));
            }
            return false;
        }

        public override int GetHashCode()
        {
            return m_first.GetHashCode() ^ m_second.GetHashCode();
        }
    };
    public class OtherType : IDataSerializable
    {
        private CData m_struct;
        private ExceptionType m_exType;

        public enum ExceptionType
        {
            None,
            Geode,
            System,
            // below are with inner exceptions
            GeodeGeode,
            GeodeSystem,
            SystemGeode,
            SystemSystem
        }

        public OtherType()
        {
            m_exType = ExceptionType.None;
        }

        public OtherType(Int32 first, Int64 second)
          : this(first, second, ExceptionType.None)
        {
        }

        public OtherType(Int32 first, Int64 second, ExceptionType exType)
        {
            m_struct.First = first;
            m_struct.Second = second;
            m_exType = exType;
        }

        public CData Data
        {
            get
            {
                return m_struct;
            }
        }

        #region IDataSerializable Members

        public void FromData(DataInput input)
        {
            m_struct.First = input.ReadInt32();
            m_struct.Second = input.ReadInt64();
            switch (m_exType)
            {
                case ExceptionType.None:
                    break;
                case ExceptionType.Geode:
                    throw new GeodeIOException("Throwing an exception");
                case ExceptionType.System:
                    throw new IOException("Throwing an exception");
                case ExceptionType.GeodeGeode:
                    throw new GeodeIOException("Throwing an exception with inner " +
                      "exception", new CacheServerException("This is an inner exception"));
                case ExceptionType.GeodeSystem:
                    throw new CacheServerException("Throwing an exception with inner " +
                      "exception", new IOException("This is an inner exception"));
                case ExceptionType.SystemGeode:
                    throw new ApplicationException("Throwing an exception with inner " +
                      "exception", new CacheServerException("This is an inner exception"));
                case ExceptionType.SystemSystem:
                    throw new ApplicationException("Throwing an exception with inner " +
                      "exception", new IOException("This is an inner exception"));
            }
        }

        public void ToData(DataOutput output)
        {
            output.WriteInt32(m_struct.First);
            output.WriteInt64(m_struct.Second);
            switch (m_exType)
            {
                case ExceptionType.None:
                    break;
                case ExceptionType.Geode:
                    throw new GeodeIOException("Throwing an exception");
                case ExceptionType.System:
                    throw new IOException("Throwing an exception");
                case ExceptionType.GeodeGeode:
                    throw new GeodeIOException("Throwing an exception with inner " +
                      "exception", new CacheServerException("This is an inner exception"));
                case ExceptionType.GeodeSystem:
                    throw new CacheServerException("Throwing an exception with inner " +
                      "exception", new IOException("This is an inner exception"));
                case ExceptionType.SystemGeode:
                    throw new ApplicationException("Throwing an exception with inner " +
                      "exception", new CacheServerException("This is an inner exception"));
                case ExceptionType.SystemSystem:
                    throw new ApplicationException("Throwing an exception with inner " +
                      "exception", new IOException("This is an inner exception"));
            }
        }

        public UInt64 ObjectSize
        {
            get
            {
                return (UInt32)(sizeof(Int32) + sizeof(Int64));
            }
        }

        #endregion

        public static ISerializable CreateDeserializable()
        {
            return new OtherType();
        }

        public override int GetHashCode()
        {
            return m_struct.First.GetHashCode() ^ m_struct.Second.GetHashCode();
        }

        public override bool Equals(object obj)
        {
            OtherType ot = obj as OtherType;
            if (ot != null)
            {
                return (m_struct.Equals(ot.m_struct));
            }
            return false;
        }
    }

    public class OtherType2 : IDataSerializable
    {
        private CData m_struct;
        private ExceptionType m_exType;

        public enum ExceptionType
        {
            None,
            Geode,
            System,
            // below are with inner exceptions
            GeodeGeode,
            GeodeSystem,
            SystemGeode,
            SystemSystem
        }

        public OtherType2()
        {
            m_exType = ExceptionType.None;
        }

        public OtherType2(Int32 first, Int64 second)
          : this(first, second, ExceptionType.None)
        {
        }

        public OtherType2(Int32 first, Int64 second, ExceptionType exType)
        {
            m_struct.First = first;
            m_struct.Second = second;
            m_exType = exType;
        }

        public CData Data
        {
            get
            {
                return m_struct;
            }
        }
        #region IDataSerializable Members

        public void FromData(DataInput input)
        {
            m_struct.First = input.ReadInt32();
            m_struct.Second = input.ReadInt64();
            switch (m_exType)
            {
                case ExceptionType.None:
                    break;
                case ExceptionType.Geode:
                    throw new GeodeIOException("Throwing an exception");
                case ExceptionType.System:
                    throw new IOException("Throwing an exception");
                case ExceptionType.GeodeGeode:
                    throw new GeodeIOException("Throwing an exception with inner " +
                      "exception", new CacheServerException("This is an inner exception"));
                case ExceptionType.GeodeSystem:
                    throw new CacheServerException("Throwing an exception with inner " +
                      "exception", new IOException("This is an inner exception"));
                case ExceptionType.SystemGeode:
                    throw new ApplicationException("Throwing an exception with inner " +
                      "exception", new CacheServerException("This is an inner exception"));
                case ExceptionType.SystemSystem:
                    throw new ApplicationException("Throwing an exception with inner " +
                      "exception", new IOException("This is an inner exception"));
            }
        }

        public void ToData(DataOutput output)
        {
            output.WriteInt32(m_struct.First);
            output.WriteInt64(m_struct.Second);
            switch (m_exType)
            {
                case ExceptionType.None:
                    break;
                case ExceptionType.Geode:
                    throw new GeodeIOException("Throwing an exception");
                case ExceptionType.System:
                    throw new IOException("Throwing an exception");
                case ExceptionType.GeodeGeode:
                    throw new GeodeIOException("Throwing an exception with inner " +
                      "exception", new CacheServerException("This is an inner exception"));
                case ExceptionType.GeodeSystem:
                    throw new CacheServerException("Throwing an exception with inner " +
                      "exception", new IOException("This is an inner exception"));
                case ExceptionType.SystemGeode:
                    throw new ApplicationException("Throwing an exception with inner " +
                      "exception", new CacheServerException("This is an inner exception"));
                case ExceptionType.SystemSystem:
                    throw new ApplicationException("Throwing an exception with inner " +
                      "exception", new IOException("This is an inner exception"));
            }
        }

        public UInt64 ObjectSize
        {
            get
            {
                return (UInt32)(sizeof(Int32) + sizeof(Int64));
            }
        }

        #endregion

        public static ISerializable CreateDeserializable()
        {
            return new OtherType2();
        }

        public override int GetHashCode()
        {
            return m_struct.First.GetHashCode() ^ m_struct.Second.GetHashCode();
        }

        public override bool Equals(object obj)
        {
            OtherType2 ot = obj as OtherType2;
            if (ot != null)
            {
                return (m_struct.Equals(ot.m_struct));
            }
            return false;
        }
    }

    [Trait("Category", "Integration")]
    public class SerializationTests : TestBase
    {
        public SerializationTests(ITestOutputHelper testOutputHelper) : base(testOutputHelper)
        {
        }

        private void putAndCheck(IRegion<object, object> region, object key, object value)
        {
            region[key] = value;
            var retrievedValue = region[key];
            Assert.Equal(value, retrievedValue);
        }


        [Fact]
        public void BuiltInSerializableTypes()
        {
            using (var cluster = new Cluster(output, CreateTestCaseDirectoryName(), 1, 1))
            {
                Assert.True(cluster.Start());
                Assert.Equal(0, cluster.Gfsh.create()
                    .region()
                    .withName("testRegion")
                    .withType("REPLICATE")
                    .execute());

                var cache = cluster.CreateCache();

                var region = cache.CreateRegionFactory(RegionShortcut.PROXY)
                    .SetPoolName("default")
                    .Create<object, object>("testRegion");
                Assert.NotNull(region);

                putAndCheck(region, "CacheableString", "foo");
                putAndCheck(region, "CacheableByte", (Byte)8);
                putAndCheck(region, "CacheableInt16", (Int16)16);
                putAndCheck(region, "CacheableInt32", (Int32)32);
                putAndCheck(region, "CacheableInt64", (Int64)64);
                putAndCheck(region, "CacheableBoolean", (Boolean)true);
                putAndCheck(region, "CacheableCharacter", 'c');
                putAndCheck(region, "CacheableDouble", (Double)1.5);
                putAndCheck(region, "CacheableFloat", (float)2.5);

                putAndCheck(region, "CacheableStringArray", new String[] { "foo", "bar" });
                putAndCheck(region, "CacheableBytes", new Byte[] { 8, 8 });
                putAndCheck(region, "CacheableInt16Array", new Int16[] { 16, 16 });
                putAndCheck(region, "CacheableInt32Array", new Int32[] { 32, 32 });
                putAndCheck(region, "CacheableInt64Array", new Int64[] { 64, 64 });
                putAndCheck(region, "CacheableBooleanArray", new Boolean[] { true, false });
                putAndCheck(region, "CacheableCharacterArray", new Char[] { 'c', 'a' });
                putAndCheck(region, "CacheableDoubleArray", new Double[] { 1.5, 1.7 });
                putAndCheck(region, "CacheableFloatArray", new float[] { 2.5F, 2.7F });

                putAndCheck(region, "CacheableDate", new DateTime());

                putAndCheck(region, "CacheableHashMap", new Dictionary<int, string>() { { 1, "one" }, { 2, "two" } });
                putAndCheck(region, "CacheableHashTable", new Hashtable() { { 1, "one" }, { 2, "two" } });
                putAndCheck(region, "CacheableVector", new ArrayList() { "one", "two" });
                putAndCheck(region, "CacheableArrayList", new List<string>() { "one", "two" });
                putAndCheck(region, "CacheableLinkedList", new LinkedList<object>(new string[] { "one", "two" }));
                putAndCheck(region, "CacheableStack", new Stack<object>(new string[] { "one", "two" }));

                {
                    var cacheableHashSet = new CacheableHashSet();
                    cacheableHashSet.Add("one");
                    cacheableHashSet.Add("two");
                    putAndCheck(region, "CacheableHashSet", cacheableHashSet);
                }

                {
                    var cacheableLinkedHashSet = new CacheableLinkedHashSet();
                    cacheableLinkedHashSet.Add("one");
                    cacheableLinkedHashSet.Add("two");
                    putAndCheck(region, "CacheableLinkedHashSet", cacheableLinkedHashSet);
                }

                cache.TypeRegistry.RegisterPdxType(PdxType.CreateDeserializable);
                putAndCheck(region, "PdxType", new PdxType());
            }
        }

        [Fact]
        public void PutGetCustomSerializableTypes()
        {
            using (var cluster = new Cluster(output, CreateTestCaseDirectoryName(), 1, 1))
            {
                Assert.True(cluster.Start());
                Assert.Equal(0, cluster.Gfsh.create()
                    .region()
                    .withName("testRegion")
                    .withType("REPLICATE")
                    .execute());
                
                var cache = cluster.CreateCache();

                cache.TypeRegistry.RegisterType(Order.CreateDeserializable, 0x42);

                var orderRegion = cache.CreateRegionFactory(RegionShortcut.PROXY)
                  .SetPoolName("default")
                  .Create<int, Order>("testRegion");
                Assert.NotNull(orderRegion);

                const int orderKey = 65;
                var order = new Order(orderKey, "Donuts", 12);

                orderRegion.Put(orderKey, order, null);
                var orderRetrieved = orderRegion.Get(orderKey, null);
                Assert.Equal(order.ToString(), orderRetrieved.ToString());

                cache.Close();
            }
        }
    }
}
