﻿#region Copyright notice and license
// Protocol Buffers - Google's data interchange format
// Copyright 2015 Google Inc.  All rights reserved.
// https://developers.google.com/protocol-buffers/
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
//     * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
//     * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
//     * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#endregion

using System;
using System.Collections.Generic;
using Google.Protobuf.TestProtos;
using NUnit.Framework;
using System.Collections;
using System.Linq;

namespace Google.Protobuf.Collections
{
    /// <summary>
    /// Tests for MapField which aren't reliant on the encoded format -
    /// tests for serialization/deserialization are part of GeneratedMessageTest.
    /// </summary>
    public class MapFieldTest
    {
        [Test]
        public void Clone_ClonesMessages()
        {
            var message = new ForeignMessage { C = 20 };
            var map = new MapField<string, ForeignMessage> { { "x", message } };
            var clone = map.Clone();
            map["x"].C = 30;
            Assert.AreEqual(20, clone["x"].C);
        }

        [Test]
        public void NullValuesProhibited()
        {
            TestNullValues<int?>(0);
            TestNullValues("");
            TestNullValues(new TestAllTypes());
        }

        private void TestNullValues<T>(T nonNullValue)
        {
            var map = new MapField<int, T>();
            var nullValue = (T) (object) null;
            Assert.Throws<ArgumentNullException>(() => map.Add(0, nullValue));
            Assert.Throws<ArgumentNullException>(() => map[0] = nullValue);
            map.Add(1, nonNullValue);
            map[1] = nonNullValue;
        }

        [Test]
        public void Add_ForbidsNullKeys()
        {
            var map = new MapField<string, ForeignMessage>();
            Assert.Throws<ArgumentNullException>(() => map.Add(null, new ForeignMessage()));
        }

        [Test]
        public void Indexer_ForbidsNullKeys()
        {
            var map = new MapField<string, ForeignMessage>();
            Assert.Throws<ArgumentNullException>(() => map[null] = new ForeignMessage());
        }

        [Test]
        public void AddPreservesInsertionOrder()
        {
            var map = new MapField<string, string>();
            map.Add("a", "v1");
            map.Add("b", "v2");
            map.Add("c", "v3");
            map.Remove("b");
            map.Add("d", "v4");
            CollectionAssert.AreEqual(new[] { "a", "c", "d" }, map.Keys);
            CollectionAssert.AreEqual(new[] { "v1", "v3", "v4" }, map.Values);
        }

        [Test]
        public void EqualityIsOrderInsensitive()
        {
            var map1 = new MapField<string, string>();
            map1.Add("a", "v1");
            map1.Add("b", "v2");

            var map2 = new MapField<string, string>();
            map2.Add("b", "v2");
            map2.Add("a", "v1");

            EqualityTester.AssertEquality(map1, map2);
        }

        [Test]
        public void EqualityIsKeySensitive()
        {
            var map1 = new MapField<string, string>();
            map1.Add("first key", "v1");
            map1.Add("second key", "v2");

            var map2 = new MapField<string, string>();
            map2.Add("third key", "v1");
            map2.Add("fourth key", "v2");

            EqualityTester.AssertInequality(map1, map2);
        }

        [Test]
        public void Equality_Simple()
        {
            var map = new MapField<string, string>();
            EqualityTester.AssertEquality(map, map);
            EqualityTester.AssertInequality(map, null);
            Assert.IsFalse(map.Equals(new object()));
        }

        [Test]
        public void EqualityIsValueSensitive()
        {
            // Note: Without some care, it's a little easier than one might
            // hope to see hash collisions, but only in some environments...
            var map1 = new MapField<string, string>();
            map1.Add("a", "first value");
            map1.Add("b", "second value");

            var map2 = new MapField<string, string>();
            map2.Add("a", "third value");
            map2.Add("b", "fourth value");

            EqualityTester.AssertInequality(map1, map2);
        }

        [Test]
        public void Add_Dictionary()
        {
            var map1 = new MapField<string, string>
            {
                { "x", "y" },
                { "a", "b" }
            };
            var map2 = new MapField<string, string>
            {
                { "before", "" },
                map1,
                { "after", "" }
            };
            var expected = new MapField<string, string>
            {
                { "before", "" },
                { "x", "y" },
                { "a", "b" },
                { "after", "" }
            };
            Assert.AreEqual(expected, map2);
            CollectionAssert.AreEqual(new[] { "before", "x", "a", "after" }, map2.Keys);
        }

        // General IDictionary<TKey, TValue> behavior tests
        [Test]
        public void Add_KeyAlreadyExists()
        {
            var map = new MapField<string, string>();
            map.Add("foo", "bar");
            Assert.Throws<ArgumentException>(() => map.Add("foo", "baz"));
        }

        [Test]
        public void Add_Pair()
        {
            var map = new MapField<string, string>();
            ICollection<KeyValuePair<string, string>> collection = map;
            collection.Add(NewKeyValuePair("x", "y"));
            Assert.AreEqual("y", map["x"]);
            Assert.Throws<ArgumentException>(() => collection.Add(NewKeyValuePair("x", "z")));
        }

        [Test]
        public void Contains_Pair()
        {
            var map = new MapField<string, string> { { "x", "y" } };
            ICollection<KeyValuePair<string, string>> collection = map;
            Assert.IsTrue(collection.Contains(NewKeyValuePair("x", "y")));
            Assert.IsFalse(collection.Contains(NewKeyValuePair("x", "z")));
            Assert.IsFalse(collection.Contains(NewKeyValuePair("z", "y")));
        }

        [Test]
        public void Remove_Key()
        {
            var map = new MapField<string, string>();
            map.Add("foo", "bar");
            Assert.AreEqual(1, map.Count);
            Assert.IsFalse(map.Remove("missing"));
            Assert.AreEqual(1, map.Count);
            Assert.IsTrue(map.Remove("foo"));
            Assert.AreEqual(0, map.Count);
            Assert.Throws<ArgumentNullException>(() => map.Remove(null));
        }

        [Test]
        public void Remove_Pair()
        {
            var map = new MapField<string, string>();
            map.Add("foo", "bar");
            ICollection<KeyValuePair<string, string>> collection = map;
            Assert.AreEqual(1, map.Count);
            Assert.IsFalse(collection.Remove(NewKeyValuePair("wrong key", "bar")));
            Assert.AreEqual(1, map.Count);
            Assert.IsFalse(collection.Remove(NewKeyValuePair("foo", "wrong value")));
            Assert.AreEqual(1, map.Count);
            Assert.IsTrue(collection.Remove(NewKeyValuePair("foo", "bar")));
            Assert.AreEqual(0, map.Count);
            Assert.Throws<ArgumentException>(() => collection.Remove(new KeyValuePair<string, string>(null, "")));
        }

        [Test]
        public void CopyTo_Pair()
        {
            var map = new MapField<string, string>();
            map.Add("foo", "bar");
            ICollection<KeyValuePair<string, string>> collection = map;
            KeyValuePair<string, string>[] array = new KeyValuePair<string, string>[3];
            collection.CopyTo(array, 1);
            Assert.AreEqual(NewKeyValuePair("foo", "bar"), array[1]);
        }

        [Test]
        public void Clear()
        {
            var map = new MapField<string, string> { { "x", "y" } };
            Assert.AreEqual(1, map.Count);
            map.Clear();
            Assert.AreEqual(0, map.Count);
            map.Add("x", "y");
            Assert.AreEqual(1, map.Count);
        }

        [Test]
        public void Indexer_Get()
        {
            var map = new MapField<string, string> { { "x", "y" } };
            Assert.AreEqual("y", map["x"]);
            Assert.Throws<KeyNotFoundException>(() => { var ignored = map["z"]; });
        }

        [Test]
        public void Indexer_Set()
        {
            var map = new MapField<string, string>();
            map["x"] = "y";
            Assert.AreEqual("y", map["x"]);
            map["x"] = "z"; // This won't throw, unlike Add.
            Assert.AreEqual("z", map["x"]);
        }

        [Test]
        public void GetEnumerator_NonGeneric()
        {
            IEnumerable map = new MapField<string, string> { { "x", "y" } };
            CollectionAssert.AreEqual(new[] { new KeyValuePair<string, string>("x", "y") },
                map.Cast<object>().ToList());
        }

        // Test for the explicitly-implemented non-generic IDictionary interface
        [Test]
        public void IDictionary_GetEnumerator()
        {
            IDictionary map = new MapField<string, string> { { "x", "y" } };
            var enumerator = map.GetEnumerator();

            // Commented assertions show an ideal situation - it looks like
            // the LinkedList enumerator doesn't throw when you ask for the current entry
            // at an inappropriate time; fixing this would be more work than it's worth.
            // Assert.Throws<InvalidOperationException>(() => enumerator.Current.GetHashCode());
            Assert.IsTrue(enumerator.MoveNext());
            Assert.AreEqual("x", enumerator.Key);
            Assert.AreEqual("y", enumerator.Value);
            Assert.AreEqual(new DictionaryEntry("x", "y"), enumerator.Current);
            Assert.AreEqual(new DictionaryEntry("x", "y"), enumerator.Entry);
            Assert.IsFalse(enumerator.MoveNext());
            // Assert.Throws<InvalidOperationException>(() => enumerator.Current.GetHashCode());
            enumerator.Reset();
            // Assert.Throws<InvalidOperationException>(() => enumerator.Current.GetHashCode());
            Assert.IsTrue(enumerator.MoveNext());
            Assert.AreEqual("x", enumerator.Key); // Assume the rest are okay
        }

        [Test]
        public void IDictionary_Add()
        {
            var map = new MapField<string, string> { { "x", "y" } };
            IDictionary dictionary = map;
            dictionary.Add("a", "b");
            Assert.AreEqual("b", map["a"]);
            Assert.Throws<ArgumentException>(() => dictionary.Add("a", "duplicate"));
            Assert.Throws<InvalidCastException>(() => dictionary.Add(new object(), "key is bad"));
            Assert.Throws<InvalidCastException>(() => dictionary.Add("value is bad", new object()));
        }

        [Test]
        public void IDictionary_Contains()
        {
            var map = new MapField<string, string> { { "x", "y" } };
            IDictionary dictionary = map;

            Assert.IsFalse(dictionary.Contains("a"));
            Assert.IsFalse(dictionary.Contains(5));
            // Surprising, but IDictionary.Contains is only about keys.
            Assert.IsFalse(dictionary.Contains(new DictionaryEntry("x", "y")));
            Assert.IsTrue(dictionary.Contains("x"));
        }

        [Test]
        public void IDictionary_Remove()
        {
            var map = new MapField<string, string> { { "x", "y" } };
            IDictionary dictionary = map;
            dictionary.Remove("a");
            Assert.AreEqual(1, dictionary.Count);
            dictionary.Remove(5);
            Assert.AreEqual(1, dictionary.Count);
            dictionary.Remove(new DictionaryEntry("x", "y"));
            Assert.AreEqual(1, dictionary.Count);
            dictionary.Remove("x");
            Assert.AreEqual(0, dictionary.Count);
            Assert.Throws<ArgumentNullException>(() => dictionary.Remove(null));
        }

        [Test]
        public void IDictionary_CopyTo()
        {
            var map = new MapField<string, string> { { "x", "y" } };
            IDictionary dictionary = map;
            var array = new DictionaryEntry[3];
            dictionary.CopyTo(array, 1);
            CollectionAssert.AreEqual(new[] { default(DictionaryEntry), new DictionaryEntry("x", "y"), default(DictionaryEntry) },
                array);
            var objectArray = new object[3];
            dictionary.CopyTo(objectArray, 1);
            CollectionAssert.AreEqual(new object[] { null, new DictionaryEntry("x", "y"), null },
                objectArray);
        }

        [Test]
        public void IDictionary_IsFixedSize()
        {
            var map = new MapField<string, string> { { "x", "y" } };
            IDictionary dictionary = map;
            Assert.IsFalse(dictionary.IsFixedSize);
        }

        [Test]
        public void IDictionary_Keys()
        {
            IDictionary dictionary = new MapField<string, string> { { "x", "y" } };
            CollectionAssert.AreEqual(new[] { "x" }, dictionary.Keys);
        }

        [Test]
        public void IDictionary_Values()
        {
            IDictionary dictionary = new MapField<string, string> { { "x", "y" } };
            CollectionAssert.AreEqual(new[] { "y" }, dictionary.Values);
        }

        [Test]
        public void IDictionary_IsSynchronized()
        {
            IDictionary dictionary = new MapField<string, string> { { "x", "y" } };
            Assert.IsFalse(dictionary.IsSynchronized);
        }

        [Test]
        public void IDictionary_SyncRoot()
        {
            IDictionary dictionary = new MapField<string, string> { { "x", "y" } };
            Assert.AreSame(dictionary, dictionary.SyncRoot);
        }

        [Test]
        public void IDictionary_Indexer_Get()
        {
            IDictionary dictionary = new MapField<string, string> { { "x", "y" } };
            Assert.AreEqual("y", dictionary["x"]);
            Assert.IsNull(dictionary["a"]);
            Assert.IsNull(dictionary[5]);
            Assert.Throws<ArgumentNullException>(() => dictionary[null].GetHashCode());
        }

        [Test]
        public void IDictionary_Indexer_Set()
        {
            var map = new MapField<string, string> { { "x", "y" } };
            IDictionary dictionary = map;
            map["a"] = "b";
            Assert.AreEqual("b", map["a"]);
            map["a"] = "c";
            Assert.AreEqual("c", map["a"]);
            Assert.Throws<InvalidCastException>(() => dictionary[5] = "x");
            Assert.Throws<InvalidCastException>(() => dictionary["x"] = 5);
            Assert.Throws<ArgumentNullException>(() => dictionary[null] = "z");
            Assert.Throws<ArgumentNullException>(() => dictionary["x"] = null);
        }

        [Test]
        public void KeysReturnsLiveView()
        {
            var map = new MapField<string, string>();
            var keys = map.Keys;
            CollectionAssert.AreEqual(new string[0], keys);
            map["foo"] = "bar";
            map["x"] = "y";
            CollectionAssert.AreEqual(new[] { "foo", "x" }, keys);
        }

        [Test]
        public void ValuesReturnsLiveView()
        {
            var map = new MapField<string, string>();
            var values = map.Values;
            CollectionAssert.AreEqual(new string[0], values);
            map["foo"] = "bar";
            map["x"] = "y";
            CollectionAssert.AreEqual(new[] { "bar", "y" }, values);
        }

        // Just test keys - we know the implementation is the same for values
        [Test]
        public void ViewsAreReadOnly()
        {
            var map = new MapField<string, string>();
            var keys = map.Keys;
            Assert.IsTrue(keys.IsReadOnly);
            Assert.Throws<NotSupportedException>(() => keys.Clear());
            Assert.Throws<NotSupportedException>(() => keys.Remove("a"));
            Assert.Throws<NotSupportedException>(() => keys.Add("a"));
        }

        // Just test keys - we know the implementation is the same for values
        [Test]
        public void ViewCopyTo()
        {
            var map = new MapField<string, string> { { "foo", "bar" }, { "x", "y" } };
            var keys = map.Keys;
            var array = new string[4];
            Assert.Throws<ArgumentException>(() => keys.CopyTo(array, 3));
            Assert.Throws<ArgumentOutOfRangeException>(() => keys.CopyTo(array, -1));
            keys.CopyTo(array, 1);
            CollectionAssert.AreEqual(new[] { null, "foo", "x", null }, array);
        }

        // Just test keys - we know the implementation is the same for values
        [Test]
        public void NonGenericViewCopyTo()
        {
            IDictionary map = new MapField<string, string> { { "foo", "bar" }, { "x", "y" } };
            ICollection keys = map.Keys;
            // Note the use of the Array type here rather than string[]
            Array array = new string[4];
            Assert.Throws<ArgumentException>(() => keys.CopyTo(array, 3));
            Assert.Throws<ArgumentOutOfRangeException>(() => keys.CopyTo(array, -1));
            keys.CopyTo(array, 1);
            CollectionAssert.AreEqual(new[] { null, "foo", "x", null }, array);
        }

        [Test]
        public void KeysContains()
        {
            var map = new MapField<string, string> { { "foo", "bar" }, { "x", "y" } };
            var keys = map.Keys;
            Assert.IsTrue(keys.Contains("foo"));
            Assert.IsFalse(keys.Contains("bar")); // It's a value!
            Assert.IsFalse(keys.Contains("1"));
            // Keys can't be null, so we should prevent contains check
            Assert.Throws<ArgumentNullException>(() => keys.Contains(null));
        }

        [Test]
        public void ValuesContains()
        {
            var map = new MapField<string, string> { { "foo", "bar" }, { "x", "y" } };
            var values = map.Values;
            Assert.IsTrue(values.Contains("bar"));
            Assert.IsFalse(values.Contains("foo")); // It's a key!
            Assert.IsFalse(values.Contains("1"));
            // Values can be null, so this makes sense
            Assert.IsFalse(values.Contains(null));
        }

        [Test]
        public void ToString_StringToString()
        {
            var map = new MapField<string, string> { { "foo", "bar" }, { "x", "y" } };
            Assert.AreEqual("{ \"foo\": \"bar\", \"x\": \"y\" }", map.ToString());
        }

        [Test]
        public void ToString_UnsupportedKeyType()
        {
            var map = new MapField<byte, string> { { 10, "foo" } };
            Assert.Throws<ArgumentException>(() => map.ToString());
        }

        private static KeyValuePair<TKey, TValue> NewKeyValuePair<TKey, TValue>(TKey key, TValue value)
        {
            return new KeyValuePair<TKey, TValue>(key, value);
        }
    }
}
