/*
 * 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
// ReSharper disable NonReadonlyMemberInGetHashCode
namespace Apache.Ignite.Core.Tests.Cache.Query
{
    using System;
    using System.Linq;
    using Apache.Ignite.Core.Binary;
    using Apache.Ignite.Core.Cache.Configuration;
    using Apache.Ignite.Core.Cache.Query;
    using Apache.Ignite.Core.Common;
    using NUnit.Framework;

    /// <summary>
    /// Tests Data Manipulation Language queries.
    /// </summary>
    public class CacheDmlQueriesTest
    {
        /// <summary>
        /// Sets up test fixture.
        /// </summary>
        [TestFixtureSetUp]
        public void FixtureSetUp()
        {
            var cfg = new IgniteConfiguration(TestUtils.GetTestConfiguration())
            {
                // Type registration is required because we call DML first and cache.Get after.
                BinaryConfiguration = new BinaryConfiguration(typeof(Foo), typeof(Key), typeof(Key2), typeof(KeyAll))
                {
                    NameMapper = GetNameMapper()
                }
            };

            Ignition.Start(cfg);
        }

        /// <summary>
        /// Gets the name mapper.
        /// </summary>
        protected virtual IBinaryNameMapper GetNameMapper()
        {
            return new BinaryBasicNameMapper {IsSimpleName = false};
        }

        /// <summary>
        /// Tears down test fixture.
        /// </summary>
        [TestFixtureTearDown]
        public void FixtureTearDown()
        {
            Ignition.StopAll(true);
        }

        /// <summary>
        /// Tests primitive key.
        /// </summary>
        [Test]
        public void TestPrimitiveKey()
        {
            var cfg = new CacheConfiguration("primitive_key", new QueryEntity(typeof(int), typeof(Foo)));
            var cache = Ignition.GetIgnite().CreateCache<int, Foo>(cfg);

            // Test insert.
            var res = cache.Query(new SqlFieldsQuery("insert into foo(_key, id, name) " +
                                                           "values (?, ?, ?), (?, ?, ?)",
                1, 2, "John", 3, 4, "Mary")).GetAll();

            Assert.AreEqual(1, res.Count);
            Assert.AreEqual(1, res[0].Count);
            Assert.AreEqual(2, res[0][0]);  // 2 affected rows

            var foos = cache.OrderBy(x => x.Key).ToArray();

            Assert.AreEqual(2, foos.Length);

            Assert.AreEqual(1, foos[0].Key);
            Assert.AreEqual(2, foos[0].Value.Id);
            Assert.AreEqual("John", foos[0].Value.Name);

            Assert.AreEqual(3, foos[1].Key);
            Assert.AreEqual(4, foos[1].Value.Id);
            Assert.AreEqual("Mary", foos[1].Value.Name);

            // Test key existence.
            Assert.IsTrue(cache.ContainsKey(1));
            Assert.IsTrue(cache.ContainsKey(3));
        }

        /// <summary>
        /// Tests the NotNull constraint.
        /// </summary>
        [Test]
        public void TestNotNull()
        {
            var cfg = new CacheConfiguration("not_null", new QueryEntity(typeof(int), typeof(Foo))
            {
                Fields = new[]
                {
                    new QueryField("id", typeof(int)) {NotNull = true},
                    new QueryField("name", typeof(string))
                }
            });

            var cache = Ignition.GetIgnite().CreateCache<int, Foo>(cfg);

            var ex = Assert.Throws<IgniteException>(() => cache.Query(new SqlFieldsQuery(
                "insert into foo(_key, name) values (?, ?)", 1, "bar")).GetAll());

            Assert.AreEqual("Null value is not allowed for column 'ID'", ex.Message);
        }

        /// <summary>
        /// Tests the NotNull constraint.
        /// </summary>
        [Test]
        public void TestNotNullAttribute()
        {
            var cfg = new CacheConfiguration("not_null_attr", new QueryEntity(typeof(int), typeof(Foo)));
            var cache = Ignition.GetIgnite().CreateCache<int, Foo>(cfg);

            var ex = Assert.Throws<IgniteException>(() => cache.Query(new SqlFieldsQuery(
                "insert into foo(_key, id) values (?, ?)", 1, 2)).GetAll());

            Assert.AreEqual("Null value is not allowed for column 'NAME'", ex.Message);
        }

        /// <summary>
        /// Tests all primitive key types.
        /// </summary>
        [Test]
        public void TestPrimitiveKeyAllTypes()
        {
            TestKey(byte.MinValue, byte.MaxValue);
            TestKey(sbyte.MinValue, sbyte.MaxValue);
            TestKey(short.MinValue, short.MaxValue);
            TestKey(int.MinValue, int.MaxValue);
            TestKey(uint.MinValue, uint.MaxValue);
            TestKey(long.MinValue, long.MaxValue);
            TestKey(ulong.MinValue, ulong.MaxValue);
            TestKey(float.MinValue, float.MaxValue);
            TestKey(double.MinValue, double.MaxValue);
            TestKey(decimal.MinValue, decimal.MaxValue);
            TestKey(Guid.NewGuid());
        }

        /// <summary>
        /// Tests the key.
        /// </summary>
        private static void TestKey<T>(params T[] vals)
        {
            var cfg = new CacheConfiguration("primitive_key_dotnet_" + typeof(T),
                new QueryEntity(typeof(T), typeof(string)));
            var cache = Ignition.GetIgnite().CreateCache<T, string>(cfg);

            foreach (var val in vals)
            {
                var res = cache.Query(new SqlFieldsQuery(
                    "insert into string(_key, _val) values (?, ?)", val, val.ToString())).GetAll();

                Assert.AreEqual(1, res.Count);
                Assert.AreEqual(1, res[0].Count);
                Assert.AreEqual(1, res[0][0]);

                Assert.AreEqual(val.ToString(), cache[val]);
            }
        }

        /// <summary>
        /// Tests composite key (which requires QueryField.IsKeyField).
        /// </summary>
        [Test]
        public void TestCompositeKey()
        {
            var cfg = new CacheConfiguration("composite_key_arr", new QueryEntity(typeof(Key), typeof(Foo)));
            var cache = Ignition.GetIgnite().CreateCache<Key, Foo>(cfg);

            // Test insert.
            var res = cache.Query(new SqlFieldsQuery("insert into foo(hi, lo, id, name) " +
                                               "values (-1, 65500, 3, 'John'), (255, 128, 6, 'Mary')")).GetAll();

            Assert.AreEqual(1, res.Count);
            Assert.AreEqual(1, res[0].Count);
            Assert.AreEqual(2, res[0][0]);  // 2 affected rows

            var foos = cache.OrderByDescending(x => x.Key.Lo).ToArray();

            Assert.AreEqual(2, foos.Length);

            Assert.AreEqual(-1, foos[0].Key.Hi);
            Assert.AreEqual(65500, foos[0].Key.Lo);
            Assert.AreEqual(3, foos[0].Value.Id);
            Assert.AreEqual("John", foos[0].Value.Name);

            Assert.AreEqual(255, foos[1].Key.Hi);
            Assert.AreEqual(128, foos[1].Key.Lo);
            Assert.AreEqual(6, foos[1].Value.Id);
            Assert.AreEqual("Mary", foos[1].Value.Name);

            // Existence tests check that hash codes are consistent.
            var binary = cache.Ignite.GetBinary();
            var binCache = cache.WithKeepBinary<IBinaryObject, IBinaryObject>();

            Assert.IsTrue(cache.ContainsKey(new Key(65500, -1)));
            Assert.IsTrue(cache.ContainsKey(foos[0].Key));
            Assert.IsTrue(binCache.ContainsKey(
                binary.GetBuilder(typeof(Key)).SetField("hi", -1).SetField("lo", 65500).Build()));
            Assert.IsTrue(binCache.ContainsKey(  // Fields are sorted.
                binary.GetBuilder(typeof(Key)).SetField("lo", 65500).SetField("hi", -1).Build()));

            Assert.IsTrue(cache.ContainsKey(new Key(128, 255)));
            Assert.IsTrue(cache.ContainsKey(foos[1].Key));
            Assert.IsTrue(binCache.ContainsKey(
                binary.GetBuilder(typeof(Key)).SetField("hi", 255).SetField("lo", 128).Build()));
            Assert.IsTrue(binCache.ContainsKey(  // Fields are sorted.
                binary.GetBuilder(typeof(Key)).SetField("lo", 128).SetField("hi", 255).Build()));
        }

        /// <summary>
        /// Tests composite key (which requires QueryField.IsKeyField).
        /// </summary>
        [Test]
        public void TestCompositeKey2()
        {
            var cfg = new CacheConfiguration("composite_key_fld", new QueryEntity(typeof(Key2), typeof(Foo)));
            var cache = Ignition.GetIgnite().CreateCache<Key2, Foo>(cfg);

            // Test insert.
            var res = cache.Query(new SqlFieldsQuery("insert into foo(hi, lo, str, id, name) " +
                                               "values (1, 2, 'Фу', 3, 'John'), (4, 5, 'Бар', 6, 'Mary')")).GetAll();

            Assert.AreEqual(1, res.Count);
            Assert.AreEqual(1, res[0].Count);
            Assert.AreEqual(2, res[0][0]);  // 2 affected rows

            var foos = cache.OrderBy(x => x.Key.Lo).ToArray();

            Assert.AreEqual(2, foos.Length);

            Assert.AreEqual(1, foos[0].Key.Hi);
            Assert.AreEqual(2, foos[0].Key.Lo);
            Assert.AreEqual("Фу", foos[0].Key.Str);
            Assert.AreEqual(3, foos[0].Value.Id);
            Assert.AreEqual("John", foos[0].Value.Name);

            Assert.AreEqual(4, foos[1].Key.Hi);
            Assert.AreEqual(5, foos[1].Key.Lo);
            Assert.AreEqual("Бар", foos[1].Key.Str);
            Assert.AreEqual(6, foos[1].Value.Id);
            Assert.AreEqual("Mary", foos[1].Value.Name);

            // Existence tests check that hash codes are consistent.
            Assert.IsTrue(cache.ContainsKey(new Key2(2, 1, "Фу")));
            Assert.IsTrue(cache.ContainsKey(foos[0].Key));

            Assert.IsTrue(cache.ContainsKey(new Key2(5, 4, "Бар")));
            Assert.IsTrue(cache.ContainsKey(foos[1].Key));
        }

        /// <summary>
        /// Tests the composite key without IsKeyField configuration.
        /// </summary>
        [Test]
        public void TestInvalidCompositeKey()
        {
            var cfg = new CacheConfiguration("invalid_composite_key", new QueryEntity
            {
                KeyTypeName = "Key",
                ValueTypeName = "Foo",
                Fields = new[]
                {
                    // Next two fields belong to the <see cref="Key"/> object, so should have been marked with <see cref="QueryField.IsKeyField"/>
                    // But if we forgot to do this - all fields are treated as value fields. Key fields have default values and second insert fails.
                    new QueryField("Lo", typeof(int)),
                    new QueryField("Hi", typeof(int)),

                    new QueryField("Id", typeof(int)),
                    new QueryField("Name", typeof(string))
                }
            });

            var cache = Ignition.GetIgnite().CreateCache<Key, Foo>(cfg);

            var ex = Assert.Throws<IgniteException>(
                () => cache.Query(new SqlFieldsQuery("insert into foo(lo, hi, id, name) " +
                                                           "values (1, 2, 3, 'John'), (4, 5, 6, 'Mary')")));

            StringAssert.StartsWith("Failed to INSERT some keys because they are already in cache", ex.Message);
        }

        /// <summary>
        /// Tests DML with pure binary cache mode, without classes.
        /// </summary>
        [Test]
        public void TestBinaryMode()
        {
            var cfg = new CacheConfiguration("binary_only", new QueryEntity
            {
                KeyTypeName = "CarKey",
                ValueTypeName = "Car",
                Fields = new[]
                {
                    new QueryField("VIN", typeof(string)) {IsKeyField = true},
                    new QueryField("Id", typeof(int)) {IsKeyField = true},
                    new QueryField("Make", typeof(string)),
                    new QueryField("Year", typeof(int))
                }
            });

            var cache = Ignition.GetIgnite().CreateCache<object, object>(cfg)
                .WithKeepBinary<IBinaryObject, IBinaryObject>();

            var res = cache.Query(new SqlFieldsQuery("insert into car(VIN, Id, Make, Year) " +
                                                           "values ('DLRDMC', 88, 'DeLorean', 1982)")).GetAll();

            Assert.AreEqual(1, res.Count);
            Assert.AreEqual(1, res[0].Count);
            Assert.AreEqual(1, res[0][0]);

            var car = cache.Single();
            Assert.AreEqual("CarKey", car.Key.GetBinaryType().TypeName);
            Assert.AreEqual("Car", car.Value.GetBinaryType().TypeName);
        }

        /// <summary>
        /// Tests the composite key with fields of all data types.
        /// </summary>
        [Test]
        public void TestCompositeKeyAllDataTypes()
        {
            var cfg = new CacheConfiguration("composite_key_all", new QueryEntity(typeof(KeyAll), typeof(string)));
            var cache = Ignition.GetIgnite().CreateCache<KeyAll, string>(cfg);

            var key = new KeyAll
            {
                Byte = byte.MaxValue,
                SByte = sbyte.MaxValue,
                Short = short.MaxValue,
                UShort = ushort.MaxValue,
                Int = int.MaxValue,
                UInt = uint.MaxValue,
                Long = long.MaxValue,
                ULong = ulong.MaxValue,
                Float = float.MaxValue,
                Double = double.MaxValue,
                Decimal = decimal.MaxValue,
                Guid = Guid.NewGuid(),
                String = "привет",
                Key = new Key(255, 65555)
            };

            // Test insert.
            var res = cache.Query(new SqlFieldsQuery(
                    "insert into string(byte, sbyte, short, ushort, int, uint, long, ulong, float, double, decimal, " +
                    "guid, string, key, _val) values (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)",
                    key.Byte, key.SByte, key.Short, key.UShort, key.Int, key.UInt, key.Long, key.ULong, key.Float,
                    key.Double, key.Decimal, key.Guid, key.String, key.Key, "VALUE"))
                .GetAll();

            Assert.AreEqual(1, res.Count);
            Assert.AreEqual(1, res[0].Count);
            Assert.AreEqual(1, res[0][0]);

            // Compare resulting keys.
            Assert.AreEqual(key, cache.Single().Key);

            // Compare keys in binary form.
            var binKey = cache.Ignite.GetBinary().ToBinary<IBinaryObject>(key);
            var binKeyRes = cache.WithKeepBinary<IBinaryObject, string>().Single().Key;

            Assert.AreEqual(binKey, binKeyRes);

            // Get by key to verify identity.
            Assert.AreEqual("VALUE", cache[key]);
        }

        /// <summary>
        /// Tests the QueryField.DefaultValue functionality.
        /// </summary>
        [Test]
        public void TestDefaultValue()
        {
            // Attribute-based config.
            var cfg = new CacheConfiguration("def_value_attr", new QueryEntity(typeof(int), typeof(Foo)));
            Assert.AreEqual(-1, cfg.QueryEntities.Single().Fields.Single(x => x.Name == "Id").DefaultValue);

            var cache = Ignition.GetIgnite().CreateCache<int, Foo>(cfg);
            Assert.AreEqual(-1,
                cache.GetConfiguration().QueryEntities.Single().Fields.Single(x => x.Name == "Id").DefaultValue);

            cache.Query(new SqlFieldsQuery("insert into foo(_key, id, name) values (?, ?, ?)", 1, 2, "John")).GetAll();
            cache.Query(new SqlFieldsQuery("insert into foo(_key, name) values (?, ?)", 3, "Mary")).GetAll();

            Assert.AreEqual(2, cache[1].Id);
            Assert.AreEqual(-1, cache[3].Id);

            // QueryEntity-based config.
            cfg = new CacheConfiguration("def_value_binary", new QueryEntity
            {
                KeyType = typeof(int),
                ValueTypeName = "DefValTest",
                Fields = new[]
                {
                    new QueryField("Name", typeof(string)) {DefaultValue = "foo"}
                }
            });

            var cache2 = Ignition.GetIgnite().CreateCache<int, int>(cfg).WithKeepBinary<int, IBinaryObject>();

            cache2.Query(new SqlFieldsQuery("insert into DefValTest(_key, name) values (?, ?)", 1, "John")).GetAll();
            cache2.Query(new SqlFieldsQuery("insert into DefValTest(_key) values (?)", 2)).GetAll();

            Assert.AreEqual("John", cache2[1].GetField<string>("Name"));
            Assert.AreEqual("foo", cache2[2].GetField<string>("Name"));
        }

        /// <summary>
        /// Key.
        /// </summary>
        private struct Key
        {
            public Key(int lo, int hi) : this()
            {
                Lo = lo;
                Hi = hi;
            }

            [QuerySqlField] public int Lo { get; private set; }
            [QuerySqlField] public int Hi { get; private set; }
        }

        /// <summary>
        /// Key.
        /// </summary>
        private struct Key2
        {
            public Key2(int lo, int hi, string str) : this()
            {
                Lo = lo;
                Hi = hi;
                Str = str;
            }

            [QuerySqlField] public int Lo { get; private set; }
            [QuerySqlField] public int Hi { get; private set; }
            [QuerySqlField] public string Str { get; private set; }
        }

        /// <summary>
        /// Value.
        /// </summary>
        private class Foo
        {
            [QuerySqlField(DefaultValue = -1)] public int Id { get; set; }
            [QuerySqlField(NotNull = true)] public string Name { get; set; }
        }

        /// <summary>
        /// Key with all kinds of fields.
        /// </summary>
        private class KeyAll
        {
            [QuerySqlField] public byte Byte { get; set; }
            [QuerySqlField] public sbyte SByte { get; set; }
            [QuerySqlField] public short Short { get; set; }
            [QuerySqlField] public ushort UShort { get; set; }
            [QuerySqlField] public int Int { get; set; }
            [QuerySqlField] public uint UInt { get; set; }
            [QuerySqlField] public long Long { get; set; }
            [QuerySqlField] public ulong ULong { get; set; }
            [QuerySqlField] public float Float { get; set; }
            [QuerySqlField] public double Double { get; set; }
            [QuerySqlField] public decimal Decimal { get; set; }
            [QuerySqlField] public Guid Guid { get; set; }
            [QuerySqlField] public string String { get; set; }
            [QuerySqlField] public Key Key { get; set; }

            private bool Equals(KeyAll other)
            {
                return Byte == other.Byte && SByte == other.SByte && Short == other.Short &&
                    UShort == other.UShort && Int == other.Int && UInt == other.UInt && Long == other.Long &&
                    ULong == other.ULong && Float.Equals(other.Float) && Double.Equals(other.Double) &&
                    Decimal == other.Decimal && Guid.Equals(other.Guid) && string.Equals(String, other.String) &&
                    Key.Equals(other.Key);
            }

            public override bool Equals(object obj)
            {
                if (ReferenceEquals(null, obj)) return false;
                if (ReferenceEquals(this, obj)) return true;
                if (obj.GetType() != GetType()) return false;
                return Equals((KeyAll) obj);
            }

            public override int GetHashCode()
            {
                unchecked
                {
                    var hashCode = Byte.GetHashCode();
                    hashCode = (hashCode * 397) ^ SByte.GetHashCode();
                    hashCode = (hashCode * 397) ^ Short.GetHashCode();
                    hashCode = (hashCode * 397) ^ UShort.GetHashCode();
                    hashCode = (hashCode * 397) ^ Int;
                    hashCode = (hashCode * 397) ^ (int) UInt;
                    hashCode = (hashCode * 397) ^ Long.GetHashCode();
                    hashCode = (hashCode * 397) ^ ULong.GetHashCode();
                    hashCode = (hashCode * 397) ^ Float.GetHashCode();
                    hashCode = (hashCode * 397) ^ Double.GetHashCode();
                    hashCode = (hashCode * 397) ^ Decimal.GetHashCode();
                    hashCode = (hashCode * 397) ^ Guid.GetHashCode();
                    hashCode = (hashCode * 397) ^ String.GetHashCode();
                    hashCode = (hashCode * 397) ^ Key.GetHashCode();
                    return hashCode;
                }
            }
        }
    }
}
