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

// ReSharper disable UnusedAutoPropertyAccessor.Local
namespace Apache.Ignite.Core.Tests.Binary
{
#if !NETCOREAPP
    extern alias ExamplesDll;
    using Apache.Ignite.ExamplesDll.Binary;
    using ExamplesAccount = ExamplesDll::Apache.Ignite.ExamplesDll.Binary.Account;
#endif

    using System;
    using System.Collections;
    using System.Collections.Generic;
    using System.IO;
    using System.Linq;
    using System.Threading;
    using System.Threading.Tasks;
    using Apache.Ignite.Core.Binary;
    using Apache.Ignite.Core.Cache.Configuration;
    using Apache.Ignite.Core.Cache.Store;
    using Apache.Ignite.Core.Common;
    using Apache.Ignite.Core.Compute;
    using Apache.Ignite.Core.Impl.Binary;
    using Apache.Ignite.Core.Impl.Common;
    using Apache.Ignite.Core.Tests.Compute;
    using NUnit.Framework;

    /// <summary>
    /// Tests the dynamic type registration.
    /// </summary>
    public class BinaryDynamicRegistrationTest
    {
        /// <summary>
        /// Executes before each test.
        /// </summary>
        [SetUp]
        public void SetUp()
        {
            ClearMarshallerWorkDir();
        }

        /// <summary>
        /// Tests the failed registration.
        /// </summary>
        [Test]
        public void TestFailedRegistration()
        {
            TestFailedRegistration<Foo>(false, false);
            TestFailedRegistration<Bin>(true, false);
            TestFailedRegistration<BinRaw>(true, true);
        }

        /// <summary>
        /// Tests the failed registration, when we write type name after the header.
        /// </summary>
        private static void TestFailedRegistration<T>(bool rawStr, bool rawInt) where T : ITest, new()
        {
            // Disable compact footers for local mode
            var cfg = new BinaryConfiguration {CompactFooter = false};

            // Test in local mode so that MarshallerContext can't propagate type registration.
            var bytes = new Marshaller(cfg).Marshal(new T {Int = 1, Str = "2"});

            var res = new Marshaller(cfg).Unmarshal<T>(bytes);

            Assert.AreEqual(1, res.Int);
            Assert.AreEqual("2", res.Str);

            // Check binary mode
            var bin = new Marshaller(cfg).Unmarshal<IBinaryObject>(bytes, BinaryMode.ForceBinary);

            if (!rawStr)
                Assert.AreEqual("2", bin.GetField<string>("Str"));

            if (!rawInt)
                Assert.AreEqual(1, bin.GetField<int>("Int"));

            res = bin.Deserialize<T>();

            Assert.AreEqual(1, res.Int);
            Assert.AreEqual("2", res.Str);
        }

        /// <summary>
        /// Tests the store with node restart to make sure type names are persisted to disk properly.
        /// </summary>
        [Test]
        public void TestStore()
        {
            var cfg = new IgniteConfiguration(TestUtils.GetTestConfiguration())
            {
                // Disable compact footers to test grid restart with persistent store
                // (Because store operates on raw binary objects).
                BinaryConfiguration = new BinaryConfiguration {CompactFooter = false},
                CacheConfiguration = new[]
                {
                    new CacheConfiguration("default")
                    {
                        CacheStoreFactory = new StoreFactory(),
                        ReadThrough = true,
                        WriteThrough = true,
                        KeepBinaryInStore = true
                    }
                }
            };

            using (var ignite = Ignition.Start(TestUtils.GetTestConfiguration()))
            {
                // Put through dynamically started cache
                var dynCache = ignite.CreateCache<int, Foo>(new CacheConfiguration("dynCache")
                {
                    CacheStoreFactory = new StoreFactory(),
                    ReadThrough = true,
                    WriteThrough = true,
                    KeepBinaryInStore = true
                });
                dynCache[2] = new Foo { Str = "test2", Int = 3 };

                // Start another server node so that store is initialized there
                using (var ignite2 = Ignition.Start(new IgniteConfiguration(TestUtils.GetTestConfiguration())
                {
                    IgniteInstanceName = "grid2"
                }))
                {
                    var dynCache2 = ignite2.GetCache<int, Foo>(dynCache.Name);

                    Assert.AreEqual("test2", dynCache2[2].Str);
                    Assert.AreEqual(3, dynCache2[2].Int);
                }
            }

            using (var ignite = Ignition.Start(cfg))
            {
                // Put through statically started cache
                var staticCache = ignite.GetCache<int, Foo>("default");
                staticCache[1] = new Foo {Str = "test", Int = 2};
            }

            using (var ignite = Ignition.Start(cfg))
            {
                var foo = ignite.GetCache<int, Foo>("default")[1];
                var foo2 = ignite.GetCache<int, Foo>("default")[2];

                Assert.AreEqual("test", foo.Str);
                Assert.AreEqual(2, foo.Int);

                Assert.AreEqual("test2", foo2.Str);
                Assert.AreEqual(3, foo2.Int);

                // Client node
                using (var igniteClient = Ignition.Start(new IgniteConfiguration(cfg)
                {
                    ClientMode = true,
                    IgniteInstanceName = "grid2"
                }))
                {
                    var fooClient = igniteClient.GetCache<int, Foo>("default")[1];
                    var fooClient2 = igniteClient.GetCache<int, Foo>("default")[2];

                    Assert.AreEqual("test", fooClient.Str);
                    Assert.AreEqual(2, fooClient.Int);

                    Assert.AreEqual("test2", fooClient2.Str);
                    Assert.AreEqual(3, fooClient2.Int);
                }
            }

            // Delete directory and check that store no longer works
            ClearMarshallerWorkDir();

            using (var ignite = Ignition.Start(cfg))
            {
                var ex = Assert.Throws<BinaryObjectException>(() => ignite.GetCache<int, Foo>("default").Get(1));

                StringAssert.Contains("Failed to resolve class name", ex.Message);
            }
        }

        /// <summary>
        /// Tests the store factory property propagation.
        /// </summary>
        [Test]
        public void TestStoreFactory()
        {
            var cfg = new IgniteConfiguration(TestUtils.GetTestConfiguration())
            {
                CacheConfiguration = new[]
                {
                    new CacheConfiguration("default")
                    {
                        CacheStoreFactory = new StoreFactory {StringProp = "test", IntProp = 9},
                        ReadThrough = true,
                        WriteThrough = true,
                        KeepBinaryInStore = true
                    }
                }
            };

            using (Ignition.Start(cfg))
            {
                var storeFactory = StoreFactory.LastInstance;

                Assert.AreEqual("test", storeFactory.StringProp);
                Assert.AreEqual(9, storeFactory.IntProp);
            }
        }

        /// <summary>
        /// Tests the single grid scenario.
        /// </summary>
        [Test]
        public void TestSingleGrid()
        {
            using (var ignite = Ignition.Start(TestUtils.GetTestConfiguration()))
            {
                Test(ignite, ignite);
            }
        }

        /// <summary>
        /// Tests the two grid scenario.
        /// </summary>
        [Test]
        public void TestTwoGrids([Values(false, true)] bool clientMode)
        {
            using (var ignite1 = Ignition.Start(TestUtils.GetTestConfiguration()))
            {
                var cfg = new IgniteConfiguration(TestUtils.GetTestConfiguration())
                {
                    IgniteInstanceName = "grid2",
                    ClientMode = clientMode
                };

                using (var ignite2 = Ignition.Start(cfg))
                {
                    Test(ignite1, ignite2);
                }

                // Test twice to verify double registration.
                using (var ignite2 = Ignition.Start(cfg))
                {
                    Test(ignite1, ignite2);
                }
            }
        }

        /// <summary>
        /// Tests the situation where newly joined node attempts registration of a known type.
        /// </summary>
        [Test]
        public void TestTwoGridsStartStop([Values(false, true)] bool clientMode)
        {
            using (Ignition.Start(TestUtils.GetTestConfiguration()))
            {
                var cfg = new IgniteConfiguration(TestUtils.GetTestConfiguration())
                {
                    IgniteInstanceName = "grid2",
                    ClientMode = clientMode
                };

                using (var ignite2 = Ignition.Start(cfg))
                {
                    var cache = ignite2.CreateCache<int, Foo>(new CacheConfiguration("foos")
                    {
                        CacheMode = CacheMode.Replicated
                    });

                    cache[1] = new Foo();
                }

                using (var ignite2 = Ignition.Start(cfg))
                {
                    var cache = ignite2.GetCache<int, Foo>("foos");

                    // ignite2 does not know that Foo class is registered in cluster, and attempts to register.
                    cache[2] = new Foo();

                    Assert.AreEqual(0, cache[1].Int);
                    Assert.AreEqual(0, cache[2].Int);
                }
            }
        }

        /// <summary>
        /// Tests interop scenario: Java and .NET exchange an object with the same type id,
        /// but marshaller cache contains different entries for different platforms for the same id.
        /// </summary>
        [Test]
        public void TestJavaInterop()
        {
            var cfg = new IgniteConfiguration(TestUtils.GetTestConfiguration())
            {
                BinaryConfiguration = new BinaryConfiguration
                {
                    NameMapper = BinaryBasicNameMapper.SimpleNameInstance
                }
            };

            using (var ignite = Ignition.Start(cfg))
            {
                var cacheCfg = new CacheConfiguration("default", new QueryEntity(typeof(PlatformComputeBinarizable))
                {
                    Fields = new[] {new QueryField("Field", typeof(int))}
                });

                var cache = ignite.CreateCache<int, object>(cacheCfg);

                // Force dynamic registration for .NET
                cache.Put(-1, new PlatformComputeBinarizable {Field = 7});
                cache.Put(ComputeApiTest.EchoTypeBinarizable, 255);

                // Run Java code that will also perform dynamic registration
                var fromJava = ignite.GetCompute().ExecuteJavaTask<PlatformComputeBinarizable>(ComputeApiTest.EchoTask,
                    ComputeApiTest.EchoTypeBinarizable);

                // Check that objects are compatible
                Assert.AreEqual(255, fromJava.Field);

                // Check that Java can read what .NET has put
                var qryRes = ignite.GetCompute().ExecuteJavaTask<IList>(
                    BinaryCompactFooterInteropTest.PlatformSqlQueryTask, "Field = 7");

                Assert.AreEqual(7, qryRes.OfType<PlatformComputeBinarizable>().Single().Field);
            }
        }

#if !NETCOREAPP
        /// <summary>
        /// Tests that types with same FullName from different assemblies are mapped to each other.
        /// </summary>
        [Test]
        public void TestSameTypeInDifferentAssemblies()
        {
            using (var ignite1 = Ignition.Start(TestUtils.GetTestConfiguration()))
            {
                var cache1 = ignite1.CreateCache<int, ExamplesAccount>("acc");
                cache1[1] = new ExamplesAccount(1, 2.2m);

                using (var ignite2 = Ignition.Start(TestUtils.GetTestConfiguration(name: "ignite2")))
                {
                    var cache2 = ignite2.GetCache<int, Account>("acc");
                    cache2[2] = new Account {Id = 2, Balance = 3.3m};

                    Assert.AreEqual(1, cache2[1].Id);  // Read ExamplesAccount as Account.
                    Assert.AreEqual(2, cache1[2].Id);  // Read Account as ExamplesAccount.
                }
            }
        }
#endif

        /// <summary>
        /// Tests registration in multiple threads.
        /// </summary>
        [Test]
        public void TestRegistrationMultithreaded([Values(true, false)] bool useTypeName)
        {
            const int iterations = 50;
            const int threads = 4;

            using (var ignite = Ignition.Start(TestUtils.GetTestConfiguration()))
            {
                var cache = ignite.CreateCache<int, int>("c").WithKeepBinary<int, IBinaryObject>();
                var bin = ignite.GetBinary();
                Func<Type, IBinaryObjectBuilder> getBuilder = x =>
                    useTypeName ? bin.GetBuilder(x.FullName) : bin.GetBuilder(x);

                var types = new[] { typeof(Foo), typeof(Bar), typeof(Bin) };

                foreach (var type in types)
                {
                    var type0 = type;  // Modified closure.

                    for (var i = 0; i < iterations; i++)
                    {
                        var countdown = new CountdownEvent(threads);

                        Action registerType = () =>
                        {
                            countdown.Signal();
                            Assert.IsTrue(countdown.Wait(5000));

                            var binObj = getBuilder(type0).SetIntField("x", 1).Build();
                            cache[1] = binObj;

                            Assert.AreEqual(binObj, cache[1]);
                        };

                        var tasks = Enumerable.Range(0, threads)
                            .Select(x => TaskRunner.Run(registerType))
                            .ToArray();

                        Task.WaitAll(tasks);
                    }
                }
            }
        }

        /// <summary>
        /// Tests the type registration.
        /// </summary>
        private static void Test(IIgnite ignite1, IIgnite ignite2)
        {
            var cfg = new CacheConfiguration("cache")
            {
                CacheMode = CacheMode.Partitioned,
                WriteSynchronizationMode = CacheWriteSynchronizationMode.FullSync
            };

            // Put on one grid.
            var cache1 = ignite1.GetOrCreateCache<int, object>(cfg);
            cache1[1] = new Foo {Int = 1, Str = "1"};
            cache1[2] = ignite1.GetBinary().GetBuilder(typeof (Bar)).SetField("Int", 5).SetField("Str", "s").Build();

            // Get on another grid.
            var cache2 = ignite2.GetOrCreateCache<int, Foo>(cfg);
            var foo = cache2[1];

            Assert.AreEqual(1, foo.Int);
            Assert.AreEqual("1", foo.Str);

            var bar = cache2.WithKeepBinary<int, IBinaryObject>()[2];

            Assert.AreEqual("s", bar.GetField<string>("Str"));
            Assert.AreEqual(5, bar.GetField<int>("Int"));

            var bar0 = bar.Deserialize<Bar>();

            Assert.AreEqual("s", bar0.Str);
            Assert.AreEqual(5, bar0.Int);

            // Test compute.
            var serverNodeCount = ignite1.GetCluster().ForServers().GetNodes().Count;

            var res0 = ignite1.GetCompute().Broadcast(new CompDateTimeFn());
            Assert.AreEqual(serverNodeCount, res0.Count);

#if !NETCOREAPP // Serializing delegates is not supported on this platform
            var res1 = ignite1.GetCompute().Broadcast(new CompFn<DateTime>(() => DateTime.Now));
            Assert.AreEqual(serverNodeCount, res1.Count);

            // Variable capture.
            var res2 = ignite1.GetCompute().Broadcast(new CompFn<string>(() => bar0.Str));
            Assert.AreEqual(Enumerable.Repeat(bar0.Str, serverNodeCount), res2);
#endif
        }

        /// <summary>
        /// Clears the marshaller work dir.
        /// </summary>
        private static void ClearMarshallerWorkDir()
        {
            // Delete all *.classname files within IGNITE_HOME
            var home = IgniteHome.Resolve();

            var files = Directory.GetFiles(home, "*.classname*", SearchOption.AllDirectories);

            files.ToList().ForEach(File.Delete);
        }

        private interface ITest
        {
            int Int { get; set; }
            string Str { get; set; }
        }

        private class Foo : ITest
        {
            public int Int { get; set; }
            public string Str { get; set; }
        }

        private class Bar : ITest
        {
            public int Int { get; set; }
            public string Str { get; set; }
        }

        private class Bin : IBinarizable, ITest
        {
            public int Int { get; set; }
            public string Str { get; set; }

            public void WriteBinary(IBinaryWriter writer)
            {
                writer.WriteInt("Int", Int);
                writer.GetRawWriter().WriteString(Str);
            }

            public void ReadBinary(IBinaryReader reader)
            {
                Int = reader.ReadInt("Int");
                Str = reader.GetRawReader().ReadString();
            }
        }

        private class BinRaw : IBinarizable, ITest
        {
            public int Int { get; set; }
            public string Str { get; set; }

            public void WriteBinary(IBinaryWriter writer)
            {
                var w = writer.GetRawWriter();

                w.WriteInt(Int);
                w.WriteString(Str);
            }

            public void ReadBinary(IBinaryReader reader)
            {
                var r = reader.GetRawReader();

                Int = r.ReadInt();
                Str = r.ReadString();
            }
        }

        [Serializable]
        private class StoreFactory : IFactory<ICacheStore>
        {
            public string StringProp { get; set; }

            public int IntProp { get; set; }

            public static StoreFactory LastInstance { get; set; }

            public ICacheStore CreateInstance()
            {
                LastInstance = this;
                return new CacheStore();
            }
        }

        private class CacheStore : CacheStoreAdapter<object, object>
        {
            private static readonly Dictionary<object, object>  Dict = new Dictionary<object, object>();

            public override object Load(object key)
            {
                object res;
                return Dict.TryGetValue(key, out res) ? res : null;
            }

            public override void Write(object key, object val)
            {
                Dict[key] = val;
            }

            public override void Delete(object key)
            {
                Dict.Remove(key);
            }
        }

#if !NETCOREAPP // Serializing delegates is not supported on this platform
        private class CompFn<T> : IComputeFunc<T>
        {
            private readonly Func<T> _func;

            public CompFn(Func<T> func)
            {
                _func = func;
            }

            public T Invoke()
            {
                return _func();
            }
        }
#endif

        private class CompDateTimeFn : IComputeFunc<DateTime>
        {
            public DateTime Invoke()
            {
                return DateTime.UtcNow;
            }
        }
    }
}

#if !NETCOREAPP
namespace Apache.Ignite.ExamplesDll.Binary
{
    /// <summary>
    /// Copy of Account class in ExamplesDll. Same name and namespace, different assembly.
    /// </summary>
    public class Account
    {
        public int Id { get; set; }

        public decimal Balance { get; set; }
    }
}
#endif
