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

namespace Apache.Ignite.Core.Tests
{
    using System;
    using System.Collections;
    using System.Collections.Concurrent;
    using System.Collections.Generic;
    using System.Diagnostics;
    using System.Diagnostics.CodeAnalysis;
    using System.Globalization;
    using System.IO;
    using System.Linq;
    using System.Reflection;
    using System.Text;
    using System.Threading;
    using Apache.Ignite.Core.Binary;
    using Apache.Ignite.Core.Cache.Affinity;
    using Apache.Ignite.Core.Client;
    using Apache.Ignite.Core.Cluster;
    using Apache.Ignite.Core.Configuration;
    using Apache.Ignite.Core.Discovery.Tcp;
    using Apache.Ignite.Core.Discovery.Tcp.Static;
    using Apache.Ignite.Core.Failure;
    using Apache.Ignite.Core.Impl;
    using Apache.Ignite.Core.Impl.Binary;
    using Apache.Ignite.Core.Impl.Client;
    using Apache.Ignite.Core.Impl.Common;
    using Apache.Ignite.Core.Impl.Unmanaged.Jni;
    using Apache.Ignite.Core.Lifecycle;
    using Apache.Ignite.Core.Log;
    using Apache.Ignite.Core.Resource;
    using Apache.Ignite.Core.Tests.Process;
    using NUnit.Framework;
    using NUnit.Framework.Interfaces;
    using NUnit.Framework.Internal;
    using ILogger = Apache.Ignite.Core.Log.ILogger;

    /// <summary>
    /// Test utility methods.
    /// </summary>
    public static class TestUtils
    {
        /** Indicates long running and/or memory/cpu intensive test. */
        public const string CategoryIntensive = "LONG_TEST";

        /** Indicates examples tests. */
        public const string CategoryExamples = "EXAMPLES_TEST";

        /** */
        public const int DfltBusywaitSleepInterval = 200;

        /** System cache name. */
        public const string UtilityCacheName = "ignite-sys-cache";

        /** */
        public const string JavaServiceName = "TestJavaService";
        
        /** Work dir. */
        private static readonly string WorkDir =
            // ReSharper disable once AssignNullToNotNullAttribute
            Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), "ignite_work");

        private static readonly IList<string> TestJvmOptsCommon = new List<string>
        {
            "-XX:+HeapDumpOnOutOfMemoryError",
            "-ea",
            "-DIGNITE_QUIET=true",
            "-Duser.timezone=UTC",
            "-DIGNITE_UPDATE_NOTIFIER=false"
        };

        /** */
        private static readonly IList<string> TestJvmOpts = (Environment.Is64BitProcess
                ? new[] { "-Xms2g", "-Xmx2g" }
                : new[] { "-Xms64m", "-Xmx99m", "-DIGNITE_ATOMIC_CACHE_DELETE_HISTORY_SIZE=1000" })
            .Concat(TestJvmOptsCommon).ToList();

        /** */
        private static readonly IList<string> JvmDebugOpts =
            new List<string> { "-Xdebug", "-Xnoagent", "-Djava.compiler=NONE", "-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=5005", "-DIGNITE_LOG_CLASSPATH_CONTENT_ON_STARTUP=false" };

        /** */
        public static bool JvmDebug = true;

        /** */
        [ThreadStatic]
        private static Random _random;

        /** */
        private static int _seed = Environment.TickCount;

        /// <summary>
        ///
        /// </summary>
        public static Random Random
        {
            get { return _random ?? (_random = new Random(Interlocked.Increment(ref _seed))); }
        }

        /// <summary>
        /// Gets current test name.
        /// </summary>
        public static string TestName
        {
            get { return TestContext.CurrentContext.Test.Name; }
        }

        /// <summary>
        ///
        /// </summary>
        /// <returns></returns>
        public static IList<string> TestJavaOptions(bool? jvmDebug = null)
        {
            IList<string> ops = new List<string>(TestJvmOpts);

            if (jvmDebug ?? JvmDebug)
            {
                foreach (string opt in JvmDebugOpts)
                    ops.Add(opt);
            }
            
            ops.Add("-Dlog4j.configurationFile=" + IgniteHome.Resolve() + "/modules/core/src/test/config/log4j2-test.xml");

            return ops;
        }

        /// <summary>
        ///
        /// </summary>
        /// <param name="action"></param>
        /// <param name="threadNum"></param>
        public static void RunMultiThreaded(Action action, int threadNum)
        {
            List<Thread> threads = new List<Thread>(threadNum);

            var errors = new ConcurrentBag<Exception>();

            for (int i = 0; i < threadNum; i++)
            {
                threads.Add(new Thread(() =>
                {
                    try
                    {
                        action();
                    }
                    catch (Exception e)
                    {
                        errors.Add(e);
                    }
                }));
            }

            foreach (Thread thread in threads)
                thread.Start();

            foreach (Thread thread in threads)
                thread.Join();

            foreach (var ex in errors)
                Assert.Fail("Unexpected exception: " + ex);
        }

        /// <summary>
        ///
        /// </summary>
        /// <param name="action"></param>
        /// <param name="threadNum"></param>
        /// <param name="duration">Duration of test execution in seconds</param>
        public static void RunMultiThreaded(Action action, int threadNum, int duration)
        {
            List<Thread> threads = new List<Thread>(threadNum);

            var errors = new ConcurrentBag<Exception>();

            bool stop = false;

            for (int i = 0; i < threadNum; i++)
            {
                threads.Add(new Thread(() =>
                {
                    try
                    {
                        while (true)
                        {
                            Thread.MemoryBarrier();

                            // ReSharper disable once AccessToModifiedClosure
                            if (stop)
                                break;

                            action();
                        }
                    }
                    catch (Exception e)
                    {
                        errors.Add(e);
                    }
                }));
            }

            foreach (Thread thread in threads)
                thread.Start();

            Thread.Sleep(duration * 1000);

            stop = true;

            Thread.MemoryBarrier();

            foreach (Thread thread in threads)
                thread.Join();

            foreach (var ex in errors)
                Assert.Fail("Unexpected exception: " + ex);
        }

        /// <summary>
        /// Wait for particular topology size.
        /// </summary>
        /// <param name="grid">Grid.</param>
        /// <param name="size">Size.</param>
        /// <param name="timeout">Timeout.</param>
        /// <returns>
        ///   <c>True</c> if topology took required size.
        /// </returns>
        public static bool WaitTopology(this IIgnite grid, int size, int timeout = 30000)
        {
            int left = timeout;

            while (true)
            {
                if (grid.GetCluster().GetNodes().Count != size)
                {
                    if (left > 0)
                    {
                        Thread.Sleep(100);

                        left -= 100;
                    }
                    else
                        break;
                }
                else
                    return true;
            }

            return false;
        }

        /// <summary>
        /// Waits for particular topology on specific cache (system cache by default).
        /// </summary>
        /// <param name="grid">Grid.</param>
        /// <param name="waitingTop">Topology version.</param>
        /// <param name="cacheName">Cache name.</param>
        /// <param name="timeout">Timeout.</param>
        /// <returns>
        ///   <c>True</c> if topology took required size.
        /// </returns>
        public static bool WaitTopology(this IIgnite grid, AffinityTopologyVersion waitingTop,
            string cacheName = UtilityCacheName, int timeout = 30000)
        {
            int checkPeriod = 200;

            // Wait for late affinity.
            for (var iter = 0;; iter++)
            {
                var result = grid.GetCompute().ExecuteJavaTask<long[]>(
                    "org.apache.ignite.platform.PlatformCacheAffinityVersionTask", cacheName);
                var top = new AffinityTopologyVersion(result[0], (int) result[1]);
                if (top.CompareTo(waitingTop) >= 0)
                {
                    Console.Out.WriteLine("Current topology: " + top);
                    break;
                }

                if (iter % 10 == 0)
                    Console.Out.WriteLine("Waiting topology cur=" + top + " wait=" + waitingTop);

                if (iter * checkPeriod > timeout)
                    return false;

                Thread.Sleep(checkPeriod);
            }

            return true;
        }

        /// <summary>
        /// Waits for condition, polling in busy wait loop.
        /// </summary>
        /// <param name="cond">Condition.</param>
        /// <param name="timeout">Timeout, in milliseconds.</param>
        /// <returns>True if condition predicate returned true within interval; false otherwise.</returns>
        public static bool WaitForCondition(Func<bool> cond, int timeout)
        {
            if (timeout <= 0)
                return cond();

            var maxTime = DateTime.Now.AddMilliseconds(timeout + DfltBusywaitSleepInterval);

            while (DateTime.Now < maxTime)
            {
                if (cond())
                    return true;

                Thread.Sleep(DfltBusywaitSleepInterval);
            }

            return false;
        }

        /// <summary>
        /// Waits for condition, polling in a busy wait loop, then asserts that condition is true.
        /// </summary>
        /// <param name="cond">Condition.</param>
        /// <param name="timeout">Timeout, in milliseconds.</param>
        /// <param name="message">Assertion message.</param>
        public static void WaitForTrueCondition(Func<bool> cond, int timeout = 1000, string message = null)
        {
            WaitForTrueCondition(cond, message == null ? (Func<string>) null : () => message, timeout);
        }

        /// <summary>
        /// Waits for condition, polling in a busy wait loop, then asserts that condition is true.
        /// </summary>
        /// <param name="cond">Condition.</param>
        /// <param name="messageFunc">Assertion message func.</param>
        /// <param name="timeout">Timeout, in milliseconds.</param>
        public static void WaitForTrueCondition(Func<bool> cond, Func<string> messageFunc, int timeout = 1000)
        {
            var res = WaitForCondition(cond, timeout);

            if (!res)
            {
                var message = string.Format("Condition not reached within {0} ms", timeout);

                if (messageFunc != null)
                {
                    message += string.Format(" ({0})", messageFunc());
                }

                Assert.IsTrue(res, message);
            }
        }

        /// <summary>
        /// Gets the static discovery.
        /// </summary>
        public static TcpDiscoverySpi GetStaticDiscovery(int? maxPort = null)
        {
            return new TcpDiscoverySpi
            {
                IpFinder = new TcpDiscoveryStaticIpFinder
                {
                    Endpoints = new[] { "127.0.0.1:47500" + (maxPort == null ? null : (".." + maxPort)) }
                },
                SocketTimeout = TimeSpan.FromSeconds(0.3)
            };
        }

        /// <summary>
        /// Gets cache keys.
        /// </summary>
        public static IEnumerable<int> GetKeys(IIgnite ignite, string cacheName,
            IClusterNode node = null, bool primary = true)
        {
            var aff = ignite.GetAffinity(cacheName);
            node = node ?? ignite.GetCluster().GetLocalNode();

            return Enumerable.Range(1, int.MaxValue).Where(x => aff.IsPrimary(node, x) == primary);
        }

        /// <summary>
        /// Gets the primary keys.
        /// </summary>
        public static IEnumerable<int> GetPrimaryKeys(IIgnite ignite, string cacheName,
            IClusterNode node = null)
        {
            return GetKeys(ignite, cacheName, node);
        }

        /// <summary>
        /// Gets the primary key.
        /// </summary>
        public static int GetPrimaryKey(IIgnite ignite, string cacheName, IClusterNode node = null)
        {
            return GetPrimaryKeys(ignite, cacheName, node).First();
        }

        /// <summary>
        /// Gets the primary key.
        /// </summary>
        public static int GetKey(IIgnite ignite, string cacheName, IClusterNode node = null, bool primaryKey = false)
        {
            return GetKeys(ignite, cacheName, node, primaryKey).First();
        }

        /// <summary>
        /// Asserts that the handle registry is empty.
        /// </summary>
        /// <param name="timeout">Timeout, in milliseconds.</param>
        /// <param name="grids">Grids to check.</param>
        public static void AssertHandleRegistryIsEmpty(int timeout, params IIgnite[] grids)
        {
            foreach (var g in grids)
                AssertHandleRegistryHasItems(g, 0, timeout);
        }

        /// <summary>
        /// Asserts that the handle registry has specified number of entries.
        /// </summary>
        /// <param name="timeout">Timeout, in milliseconds.</param>
        /// <param name="expectedCount">Expected item count.</param>
        /// <param name="grids">Grids to check.</param>
        public static void AssertHandleRegistryHasItems(int timeout, int expectedCount, params IIgnite[] grids)
        {
            foreach (var g in grids)
                AssertHandleRegistryHasItems(g, expectedCount, timeout);
        }

        /// <summary>
        /// Asserts that the handle registry has specified number of entries.
        /// </summary>
        /// <param name="grid">The grid to check.</param>
        /// <param name="expectedCount">Expected item count.</param>
        /// <param name="timeout">Timeout, in milliseconds.</param>
        public static void AssertHandleRegistryHasItems(IIgnite grid, int expectedCount, int timeout)
        {
            Func<IEnumerable<KeyValuePair<long, object>>> getItems = () =>
                ((Ignite)grid).HandleRegistry.GetItems().Where(x => !(x.Value is LifecycleHandlerHolder));

            if (WaitForCondition(() => getItems().Count() == expectedCount, timeout))
                return;

            var items = getItems().ToList();

            if (items.Any())
            {
                Assert.Fail("HandleRegistry is not empty in grid '{0}' (expected {1}, actual {2}):\n '{3}'",
                    grid.Name, expectedCount, items.Count,
                    items.Select(x => x.ToString()).Aggregate((x, y) => x + "\n" + y));
            }
        }

        /// <summary>
        /// Serializes and deserializes back an object.
        /// </summary>
        public static T SerializeDeserialize<T>(T obj, bool raw = false)
        {
            var cfg = new BinaryConfiguration
            {
                Serializer = raw ? new BinaryReflectiveSerializer {RawMode = true} : null
            };

            var marsh = new Marshaller(cfg) { CompactFooter = false };

            return marsh.Unmarshal<T>(marsh.Marshal(obj));
        }

        /// <summary>
        /// Clears the work dir.
        /// </summary>
        public static void ClearWorkDir()
        {
            if (!Directory.Exists(WorkDir))
            {
                return;
            }

            // Delete everything we can. Some files may be locked.
            foreach (var e in Directory.GetFileSystemEntries(WorkDir, "*", SearchOption.AllDirectories))
            {
                try
                {
                    File.Delete(e);
                }
                catch (Exception)
                {
                    // Ignore
                }

                try
                {
                    Directory.Delete(e, true);
                }
                catch (Exception)
                {
                    // Ignore
                }
            }
        }

        /// <summary>
        /// Gets the dot net source dir.
        /// </summary>
        public static DirectoryInfo GetDotNetSourceDir()
        {
            // ReSharper disable once AssignNullToNotNullAttribute
            var dir = new DirectoryInfo(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location));

            while (dir != null)
            {
                if (dir.GetFiles().Any(x => x.Name == "Apache.Ignite.sln"))
                    return dir;

                dir = dir.Parent;
            }

            throw new InvalidOperationException("Could not resolve Ignite.NET source directory.");
        }

        /// <summary>
        /// Gets a value indicating whether specified partition is reserved.
        /// </summary>
        public static bool IsPartitionReserved(IIgnite ignite, string cacheName, int part)
        {
            Debug.Assert(ignite != null);
            Debug.Assert(cacheName != null);

            const string taskName = "org.apache.ignite.platform.PlatformIsPartitionReservedTask";

            return ignite.GetCompute().ExecuteJavaTask<bool>(taskName, new object[] {cacheName, part});
        }

        /// <summary>
        /// Gets the innermost exception.
        /// </summary>
        public static Exception GetInnermostException(this Exception ex)
        {
            while (ex.InnerException != null)
            {
                ex = ex.InnerException;
            }

            return ex;
        }

        /// <summary>
        /// Gets the private field value.
        /// </summary>
        public static T GetPrivateField<T>(object obj, string name)
        {
            Assert.IsNotNull(obj);

            var field = obj.GetType().GetField(name, BindingFlags.Instance | BindingFlags.NonPublic);

            Assert.IsNotNull(field);

            return (T) field.GetValue(obj);
        }

        /// <summary>
        /// Gets active notification listeners.
        /// </summary>
        public static ICollection GetActiveNotificationListeners(this IIgniteClient client)
        {
            var failoverSocket = GetPrivateField<ClientFailoverSocket>(client, "_socket");
            var socket = GetPrivateField<ClientSocket>(failoverSocket, "_socket");
            return GetPrivateField<ICollection>(socket, "_notificationListeners");
        }

                /// <summary>
        ///
        /// </summary>
        /// <returns></returns>
        public static string CreateTestClasspath()
        {
            var home = IgniteHome.Resolve();
            return Classpath.CreateClasspath(null, home, forceTestClasspath: true);
        }

        /// <summary>
        /// Kill Ignite processes.
        /// </summary>
        public static void KillProcesses()
        {
            IgniteProcess.KillAll();
        }

        /// <summary>
        /// Gets the default code-based test configuration.
        /// </summary>
        public static IgniteConfiguration GetTestConfiguration(bool? jvmDebug = null, string name = null, bool noLogger = false)
        {
            return new IgniteConfiguration
            {
                DiscoverySpi = GetStaticDiscovery(),
                Localhost = "127.0.0.1",
                JvmOptions = TestJavaOptions(jvmDebug),
                JvmClasspath = CreateTestClasspath(),
                IgniteInstanceName = name,
                DataStorageConfiguration = new DataStorageConfiguration
                {
                    DefaultDataRegionConfiguration = new DataRegionConfiguration
                    {
                        Name = DataStorageConfiguration.DefaultDataRegionName,
                        InitialSize = 128 * 1024 * 1024,
                        MaxSize = Environment.Is64BitProcess
                            ? DataRegionConfiguration.DefaultMaxSize
                            : 256 * 1024 * 1024
                    }
                },
                FailureHandler = new NoOpFailureHandler(),
                WorkDirectory = WorkDir,
                Logger = noLogger ? null : new TestContextLogger()
            };
        }

        /// <summary>
        /// Creates the JVM if necessary.
        /// </summary>
        public static void EnsureJvmCreated()
        {
            if (Jvm.Get(true) == null)
            {
                var logger = new TestContextLogger();
                JvmDll.Load(null, logger);
                IgniteManager.CreateJvm(GetTestConfiguration(), logger);
            }
        }

        /// <summary>
        /// Runs the test in new process.
        /// </summary>
        [SuppressMessage("ReSharper", "AssignNullToNotNullAttribute")]
        public static void RunTestInNewProcess(string fixtureName, string testName)
        {
            var procStart = new ProcessStartInfo
            {
                FileName = typeof(TestUtils).Assembly.Location,
                Arguments = fixtureName + " " + testName,
                CreateNoWindow = true,
                UseShellExecute = false,
                RedirectStandardOutput = true,
                RedirectStandardError = true
            };

            var proc = System.Diagnostics.Process.Start(procStart);
            Assert.IsNotNull(proc);

            try
            {
                var reader = new ListDataReader();
                proc.AttachProcessConsoleReader(reader, new IgniteProcessConsoleOutputReader());

                Assert.IsTrue(proc.WaitForExit(50000), string.Join("\n", reader.GetOutput()));
                Assert.AreEqual(0, proc.ExitCode, string.Join("\n", reader.GetOutput()));
            }
            finally
            {
                if (!proc.HasExited)
                {
                    proc.Kill();
                }
            }
        }

        /// <summary>
        /// Deploys the Java service on all or specified nodes.
        /// </summary>
        public static void DeployJavaService(IIgnite ignite, IEnumerable<object> nodes = null)
        {
            ignite.GetCompute()
                .ExecuteJavaTask<object>("org.apache.ignite.platform.PlatformDeployServiceTask", nodes?.ToArray());

            var services = ignite.GetServices();

            WaitForCondition(() => services.GetServiceDescriptors().Any(x => x.Name == TestUtils.JavaServiceName), 1000);
        }

        /// <summary>
        /// Logs to test progress. Produces immediate console output on .NET Core.
        /// </summary>
        public class TestContextLogger : ILogger
        {
            private readonly TestExecutionContext _ctx = TestExecutionContext.CurrentContext;

            private readonly ITestListener _listener;

            public TestContextLogger()
            {
                var prop = _ctx.GetType().GetProperty("Listener", BindingFlags.Instance | BindingFlags.NonPublic);

                Debug.Assert(prop != null);

                _listener = (ITestListener)prop.GetValue(_ctx);
            }

            /** <inheritdoc /> */
            public void Log(LogLevel level, string message, object[] args, IFormatProvider formatProvider,
                string category, string nativeErrorInfo, Exception ex)
            {
                if (!IsEnabled(level))
                {
                    return;
                }

                var sb = new StringBuilder();

                if (args != null)
                {
                    sb.AppendFormat(formatProvider ?? CultureInfo.InvariantCulture, message, args);
                }
                else
                {
                    sb.Append(message);
                }

                if (nativeErrorInfo != null)
                {
                    sb.Append(Environment.NewLine).Append(nativeErrorInfo);
                }

                if (ex != null)
                {
                    sb.Append(Environment.NewLine).Append(ex);
                }

                sb.Append(Environment.NewLine);

                var output = new TestOutput(
                    text: sb.ToString(),
                    stream: "Progress",
                    testId: _ctx.CurrentTest?.Id,
                    testName: _ctx.CurrentTest?.FullName);

                _listener.TestOutput(output);
            }

            /** <inheritdoc /> */
            public bool IsEnabled(LogLevel level)
            {
                return level >= LogLevel.Info;
            }
        }
    }

    /** */
    public  class SetUseBinaryArray : ILifecycleHandler
    {
        /** Task name. */
        private const string SetUseTypedArrayTask = "org.apache.ignite.platform.PlatformSetUseBinaryArrayTask";

        /** */
        [InstanceResource]
        private readonly IIgnite _ignite = null;

        /** <inheritdoc /> */
        public void OnLifecycleEvent(LifecycleEventType evt)
        {
            if (evt != LifecycleEventType.AfterNodeStart && evt != LifecycleEventType.BeforeNodeStop)
                return;

            _ignite.GetCompute()
                .ExecuteJavaTask<object>(SetUseTypedArrayTask, evt == LifecycleEventType.AfterNodeStart);
        }
    }
}
