﻿#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 Google.Protobuf.Compatibility;
using Google.Protobuf.Reflection;
using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Linq;

namespace Google.Protobuf.Collections
{
    /// <summary>
    /// Representation of a map field in a Protocol Buffer message.
    /// </summary>
    /// <typeparam name="TKey">Key type in the map. Must be a type supported by Protocol Buffer map keys.</typeparam>
    /// <typeparam name="TValue">Value type in the map. Must be a type supported by Protocol Buffers.</typeparam>
    /// <remarks>
    /// <para>
    /// For string keys, the equality comparison is provided by <see cref="StringComparer.Ordinal" />.
    /// </para>
    /// <para>
    /// Null values are not permitted in the map, either for wrapper types or regular messages.
    /// If a map is deserialized from a data stream and the value is missing from an entry, a default value
    /// is created instead. For primitive types, that is the regular default value (0, the empty string and so
    /// on); for message types, an empty instance of the message is created, as if the map entry contained a 0-length
    /// encoded value for the field.
    /// </para>
    /// <para>
    /// This implementation does not generally prohibit the use of key/value types which are not
    /// supported by Protocol Buffers (e.g. using a key type of <code>byte</code>) but nor does it guarantee
    /// that all operations will work in such cases.
    /// </para>
    /// <para>
    /// The order in which entries are returned when iterating over this object is undefined, and may change
    /// in future versions.
    /// </para>
    /// </remarks>
    public sealed class MapField<TKey, TValue> : IDeepCloneable<MapField<TKey, TValue>>, IDictionary<TKey, TValue>, IEquatable<MapField<TKey, TValue>>, IDictionary
#if !NET35
        , IReadOnlyDictionary<TKey, TValue>
#endif
    {
        private static readonly EqualityComparer<TValue> ValueEqualityComparer = ProtobufEqualityComparers.GetEqualityComparer<TValue>();
        private static readonly EqualityComparer<TKey> KeyEqualityComparer = ProtobufEqualityComparers.GetEqualityComparer<TKey>();

        // TODO: Don't create the map/list until we have an entry. (Assume many maps will be empty.)
        private readonly Dictionary<TKey, LinkedListNode<KeyValuePair<TKey, TValue>>> map =
            new Dictionary<TKey, LinkedListNode<KeyValuePair<TKey, TValue>>>(KeyEqualityComparer);
        private readonly LinkedList<KeyValuePair<TKey, TValue>> list = new LinkedList<KeyValuePair<TKey, TValue>>();

        /// <summary>
        /// Creates a deep clone of this object.
        /// </summary>
        /// <returns>
        /// A deep clone of this object.
        /// </returns>
        public MapField<TKey, TValue> Clone()
        {
            var clone = new MapField<TKey, TValue>();
            // Keys are never cloneable. Values might be.
            if (typeof(IDeepCloneable<TValue>).IsAssignableFrom(typeof(TValue)))
            {
                foreach (var pair in list)
                {
                    clone.Add(pair.Key, ((IDeepCloneable<TValue>)pair.Value).Clone());
                }
            }
            else
            {
                // Nothing is cloneable, so we don't need to worry.
                clone.Add(this);
            }
            return clone;
        }

        /// <summary>
        /// Adds the specified key/value pair to the map.
        /// </summary>
        /// <remarks>
        /// This operation fails if the key already exists in the map. To replace an existing entry, use the indexer.
        /// </remarks>
        /// <param name="key">The key to add</param>
        /// <param name="value">The value to add.</param>
        /// <exception cref="System.ArgumentException">The given key already exists in map.</exception>
        public void Add(TKey key, TValue value)
        {
            // Validation of arguments happens in ContainsKey and the indexer
            if (ContainsKey(key))
            {
                throw new ArgumentException("Key already exists in map", nameof(key));
            }
            this[key] = value;
        }

        /// <summary>
        /// Determines whether the specified key is present in the map.
        /// </summary>
        /// <param name="key">The key to check.</param>
        /// <returns><c>true</c> if the map contains the given key; <c>false</c> otherwise.</returns>
        public bool ContainsKey(TKey key)
        {
            ProtoPreconditions.CheckNotNullUnconstrained(key, nameof(key));
            return map.ContainsKey(key);
        }

        private bool ContainsValue(TValue value) =>
            list.Any(pair => ValueEqualityComparer.Equals(pair.Value, value));

        /// <summary>
        /// Removes the entry identified by the given key from the map.
        /// </summary>
        /// <param name="key">The key indicating the entry to remove from the map.</param>
        /// <returns><c>true</c> if the map contained the given key before the entry was removed; <c>false</c> otherwise.</returns>
        public bool Remove(TKey key)
        {
            ProtoPreconditions.CheckNotNullUnconstrained(key, nameof(key));
            LinkedListNode<KeyValuePair<TKey, TValue>> node;
            if (map.TryGetValue(key, out node))
            {
                map.Remove(key);
                node.List.Remove(node);
                return true;
            }
            else
            {
                return false;
            }
        }

        /// <summary>
        /// Gets the value associated with the specified key.
        /// </summary>
        /// <param name="key">The key whose value to get.</param>
        /// <param name="value">When this method returns, the value associated with the specified key, if the key is found;
        /// otherwise, the default value for the type of the <paramref name="value"/> parameter.
        /// This parameter is passed uninitialized.</param>
        /// <returns><c>true</c> if the map contains an element with the specified key; otherwise, <c>false</c>.</returns>
        public bool TryGetValue(TKey key, out TValue value)
        {
            LinkedListNode<KeyValuePair<TKey, TValue>> node;
            if (map.TryGetValue(key, out node))
            {
                value = node.Value.Value;
                return true;
            }
            else
            {
                value = default(TValue);
                return false;
            }
        }

        /// <summary>
        /// Gets or sets the value associated with the specified key.
        /// </summary>
        /// <param name="key">The key of the value to get or set.</param>
        /// <exception cref="KeyNotFoundException">The property is retrieved and key does not exist in the collection.</exception>
        /// <returns>The value associated with the specified key. If the specified key is not found,
        /// a get operation throws a <see cref="KeyNotFoundException"/>, and a set operation creates a new element with the specified key.</returns>
        public TValue this[TKey key]
        {
            get
            {
                ProtoPreconditions.CheckNotNullUnconstrained(key, nameof(key));
                TValue value;
                if (TryGetValue(key, out value))
                {
                    return value;
                }
                throw new KeyNotFoundException();
            }
            set
            {
                ProtoPreconditions.CheckNotNullUnconstrained(key, nameof(key));
                // value == null check here is redundant, but avoids boxing.
                if (value == null)
                {
                    ProtoPreconditions.CheckNotNullUnconstrained(value, nameof(value));
                }
                LinkedListNode<KeyValuePair<TKey, TValue>> node;
                var pair = new KeyValuePair<TKey, TValue>(key, value);
                if (map.TryGetValue(key, out node))
                {
                    node.Value = pair;
                }
                else
                {
                    node = list.AddLast(pair);
                    map[key] = node;
                }
            }
        }

        /// <summary>
        /// Gets a collection containing the keys in the map.
        /// </summary>
        public ICollection<TKey> Keys { get { return new MapView<TKey>(this, pair => pair.Key, ContainsKey); } }

        /// <summary>
        /// Gets a collection containing the values in the map.
        /// </summary>
        public ICollection<TValue> Values { get { return new MapView<TValue>(this, pair => pair.Value, ContainsValue); } }

        /// <summary>
        /// Adds the specified entries to the map. The keys and values are not automatically cloned.
        /// </summary>
        /// <param name="entries">The entries to add to the map.</param>
        public void Add(IDictionary<TKey, TValue> entries)
        {
            ProtoPreconditions.CheckNotNull(entries, nameof(entries));
            foreach (var pair in entries)
            {
                Add(pair.Key, pair.Value);
            }
        }

        /// <summary>
        /// Returns an enumerator that iterates through the collection.
        /// </summary>
        /// <returns>
        /// An enumerator that can be used to iterate through the collection.
        /// </returns>
        public IEnumerator<KeyValuePair<TKey, TValue>> GetEnumerator()
        {
            return list.GetEnumerator();
        }

        /// <summary>
        /// Returns an enumerator that iterates through a collection.
        /// </summary>
        /// <returns>
        /// An <see cref="T:System.Collections.IEnumerator" /> object that can be used to iterate through the collection.
        /// </returns>
        IEnumerator IEnumerable.GetEnumerator()
        {
            return GetEnumerator();
        }

        /// <summary>
        /// Adds the specified item to the map.
        /// </summary>
        /// <param name="item">The item to add to the map.</param>
        void ICollection<KeyValuePair<TKey, TValue>>.Add(KeyValuePair<TKey, TValue> item)
        {
            Add(item.Key, item.Value);
        }

        /// <summary>
        /// Removes all items from the map.
        /// </summary>
        public void Clear()
        {
            list.Clear();
            map.Clear();
        }

        /// <summary>
        /// Determines whether map contains an entry equivalent to the given key/value pair.
        /// </summary>
        /// <param name="item">The key/value pair to find.</param>
        /// <returns></returns>
        bool ICollection<KeyValuePair<TKey, TValue>>.Contains(KeyValuePair<TKey, TValue> item)
        {
            TValue value;
            return TryGetValue(item.Key, out value) && ValueEqualityComparer.Equals(item.Value, value);
        }

        /// <summary>
        /// Copies the key/value pairs in this map to an array.
        /// </summary>
        /// <param name="array">The array to copy the entries into.</param>
        /// <param name="arrayIndex">The index of the array at which to start copying values.</param>
        void ICollection<KeyValuePair<TKey, TValue>>.CopyTo(KeyValuePair<TKey, TValue>[] array, int arrayIndex)
        {
            list.CopyTo(array, arrayIndex);
        }

        /// <summary>
        /// Removes the specified key/value pair from the map.
        /// </summary>
        /// <remarks>Both the key and the value must be found for the entry to be removed.</remarks>
        /// <param name="item">The key/value pair to remove.</param>
        /// <returns><c>true</c> if the key/value pair was found and removed; <c>false</c> otherwise.</returns>
        bool ICollection<KeyValuePair<TKey, TValue>>.Remove(KeyValuePair<TKey, TValue> item)
        {
            if (item.Key == null)
            {
                throw new ArgumentException("Key is null", nameof(item));
            }
            LinkedListNode<KeyValuePair<TKey, TValue>> node;
            if (map.TryGetValue(item.Key, out node) &&
                EqualityComparer<TValue>.Default.Equals(item.Value, node.Value.Value))
            {
                map.Remove(item.Key);
                node.List.Remove(node);
                return true;
            }
            else
            {
                return false;
            }
        }

        /// <summary>
        /// Gets the number of elements contained in the map.
        /// </summary>
        public int Count { get { return list.Count; } }

        /// <summary>
        /// Gets a value indicating whether the map is read-only.
        /// </summary>
        public bool IsReadOnly { get { return false; } }

        /// <summary>
        /// Determines whether the specified <see cref="System.Object" />, is equal to this instance.
        /// </summary>
        /// <param name="other">The <see cref="System.Object" /> to compare with this instance.</param>
        /// <returns>
        ///   <c>true</c> if the specified <see cref="System.Object" /> is equal to this instance; otherwise, <c>false</c>.
        /// </returns>
        public override bool Equals(object other)
        {
            return Equals(other as MapField<TKey, TValue>);
        }

        /// <summary>
        /// Returns a hash code for this instance.
        /// </summary>
        /// <returns>
        /// A hash code for this instance, suitable for use in hashing algorithms and data structures like a hash table. 
        /// </returns>
        public override int GetHashCode()
        {
            var keyComparer = KeyEqualityComparer;
            var valueComparer = ValueEqualityComparer;
            int hash = 0;
            foreach (var pair in list)
            {
                hash ^= keyComparer.GetHashCode(pair.Key) * 31 + valueComparer.GetHashCode(pair.Value);
            }
            return hash;
        }

        /// <summary>
        /// Compares this map with another for equality.
        /// </summary>
        /// <remarks>
        /// The order of the key/value pairs in the maps is not deemed significant in this comparison.
        /// </remarks>
        /// <param name="other">The map to compare this with.</param>
        /// <returns><c>true</c> if <paramref name="other"/> refers to an equal map; <c>false</c> otherwise.</returns>
        public bool Equals(MapField<TKey, TValue> other)
        {
            if (other == null)
            {
                return false;
            }
            if (other == this)
            {
                return true;
            }
            if (other.Count != this.Count)
            {
                return false;
            }
            var valueComparer = ValueEqualityComparer;
            foreach (var pair in this)
            {
                TValue value;
                if (!other.TryGetValue(pair.Key, out value))
                {
                    return false;
                }
                if (!valueComparer.Equals(value, pair.Value))
                {
                    return false;
                }
            }
            return true;
        }

        /// <summary>
        /// Adds entries to the map from the given stream.
        /// </summary>
        /// <remarks>
        /// It is assumed that the stream is initially positioned after the tag specified by the codec.
        /// This method will continue reading entries from the stream until the end is reached, or
        /// a different tag is encountered.
        /// </remarks>
        /// <param name="input">Stream to read from</param>
        /// <param name="codec">Codec describing how the key/value pairs are encoded</param>
        public void AddEntriesFrom(CodedInputStream input, Codec codec)
        {
            var adapter = new Codec.MessageAdapter(codec);
            do
            {
                adapter.Reset();
                input.ReadMessage(adapter);
                this[adapter.Key] = adapter.Value;
            } while (input.MaybeConsumeTag(codec.MapTag));
        }

        /// <summary>
        /// Writes the contents of this map to the given coded output stream, using the specified codec
        /// to encode each entry.
        /// </summary>
        /// <param name="output">The output stream to write to.</param>
        /// <param name="codec">The codec to use for each entry.</param>
        public void WriteTo(CodedOutputStream output, Codec codec)
        {
            var message = new Codec.MessageAdapter(codec);
            foreach (var entry in list)
            {
                message.Key = entry.Key;
                message.Value = entry.Value;
                output.WriteTag(codec.MapTag);
                output.WriteMessage(message);
            }
        }

        /// <summary>
        /// Calculates the size of this map based on the given entry codec.
        /// </summary>
        /// <param name="codec">The codec to use to encode each entry.</param>
        /// <returns></returns>
        public int CalculateSize(Codec codec)
        {
            if (Count == 0)
            {
                return 0;
            }
            var message = new Codec.MessageAdapter(codec);
            int size = 0;
            foreach (var entry in list)
            {
                message.Key = entry.Key;
                message.Value = entry.Value;
                size += CodedOutputStream.ComputeRawVarint32Size(codec.MapTag);
                size += CodedOutputStream.ComputeMessageSize(message);
            }
            return size;
        }

        /// <summary>
        /// Returns a string representation of this repeated field, in the same
        /// way as it would be represented by the default JSON formatter.
        /// </summary>
        public override string ToString()
        {
            var writer = new StringWriter();
            JsonFormatter.Default.WriteDictionary(writer, this);
            return writer.ToString();
        }

        #region IDictionary explicit interface implementation
        void IDictionary.Add(object key, object value)
        {
            Add((TKey)key, (TValue)value);
        }

        bool IDictionary.Contains(object key)
        {
            if (!(key is TKey))
            {
                return false;
            }
            return ContainsKey((TKey)key);
        }

        IDictionaryEnumerator IDictionary.GetEnumerator()
        {
            return new DictionaryEnumerator(GetEnumerator());
        }

        void IDictionary.Remove(object key)
        {
            ProtoPreconditions.CheckNotNull(key, nameof(key));
            if (!(key is TKey))
            {
                return;
            }
            Remove((TKey)key);
        }

        void ICollection.CopyTo(Array array, int index)
        {
            // This is ugly and slow as heck, but with any luck it will never be used anyway.
            ICollection temp = this.Select(pair => new DictionaryEntry(pair.Key, pair.Value)).ToList();
            temp.CopyTo(array, index);
        }

        bool IDictionary.IsFixedSize { get { return false; } }

        ICollection IDictionary.Keys { get { return (ICollection)Keys; } }

        ICollection IDictionary.Values { get { return (ICollection)Values; } }

        bool ICollection.IsSynchronized { get { return false; } }

        object ICollection.SyncRoot { get { return this; } }

        object IDictionary.this[object key]
        {
            get
            {
                ProtoPreconditions.CheckNotNull(key, nameof(key));
                if (!(key is TKey))
                {
                    return null;
                }
                TValue value;
                TryGetValue((TKey)key, out value);
                return value;
            }

            set
            {
                this[(TKey)key] = (TValue)value;
            }
        }
        #endregion

        #region IReadOnlyDictionary explicit interface implementation
#if !NET35
        IEnumerable<TKey> IReadOnlyDictionary<TKey, TValue>.Keys => Keys;

        IEnumerable<TValue> IReadOnlyDictionary<TKey, TValue>.Values => Values;
#endif
        #endregion

        private class DictionaryEnumerator : IDictionaryEnumerator
        {
            private readonly IEnumerator<KeyValuePair<TKey, TValue>> enumerator;

            internal DictionaryEnumerator(IEnumerator<KeyValuePair<TKey, TValue>> enumerator)
            {
                this.enumerator = enumerator;
            }

            public bool MoveNext()
            {
                return enumerator.MoveNext();
            }

            public void Reset()
            {
                enumerator.Reset();
            }

            public object Current { get { return Entry; } }
            public DictionaryEntry Entry { get { return new DictionaryEntry(Key, Value); } }
            public object Key { get { return enumerator.Current.Key; } }
            public object Value { get { return enumerator.Current.Value; } }
        }

        /// <summary>
        /// A codec for a specific map field. This contains all the information required to encode and
        /// decode the nested messages.
        /// </summary>
        public sealed class Codec
        {
            private readonly FieldCodec<TKey> keyCodec;
            private readonly FieldCodec<TValue> valueCodec;
            private readonly uint mapTag;

            /// <summary>
            /// Creates a new entry codec based on a separate key codec and value codec,
            /// and the tag to use for each map entry.
            /// </summary>
            /// <param name="keyCodec">The key codec.</param>
            /// <param name="valueCodec">The value codec.</param>
            /// <param name="mapTag">The map tag to use to introduce each map entry.</param>
            public Codec(FieldCodec<TKey> keyCodec, FieldCodec<TValue> valueCodec, uint mapTag)
            {
                this.keyCodec = keyCodec;
                this.valueCodec = valueCodec;
                this.mapTag = mapTag;
            }

            /// <summary>
            /// The tag used in the enclosing message to indicate map entries.
            /// </summary>
            internal uint MapTag { get { return mapTag; } }

            /// <summary>
            /// A mutable message class, used for parsing and serializing. This
            /// delegates the work to a codec, but implements the <see cref="IMessage"/> interface
            /// for interop with <see cref="CodedInputStream"/> and <see cref="CodedOutputStream"/>.
            /// This is nested inside Codec as it's tightly coupled to the associated codec,
            /// and it's simpler if it has direct access to all its fields.
            /// </summary>
            internal class MessageAdapter : IMessage
            {
                private static readonly byte[] ZeroLengthMessageStreamData = new byte[] { 0 };

                private readonly Codec codec;
                internal TKey Key { get; set; }
                internal TValue Value { get; set; }

                internal MessageAdapter(Codec codec)
                {
                    this.codec = codec;
                }

                internal void Reset()
                {
                    Key = codec.keyCodec.DefaultValue;
                    Value = codec.valueCodec.DefaultValue;
                }

                public void MergeFrom(CodedInputStream input)
                {
                    uint tag;
                    while ((tag = input.ReadTag()) != 0)
                    {
                        if (tag == codec.keyCodec.Tag)
                        {
                            Key = codec.keyCodec.Read(input);
                        }
                        else if (tag == codec.valueCodec.Tag)
                        {
                            Value = codec.valueCodec.Read(input);
                        }
                        else 
                        {
                            input.SkipLastField();
                        }
                    }

                    // Corner case: a map entry with a key but no value, where the value type is a message.
                    // Read it as if we'd seen an input stream with no data (i.e. create a "default" message).
                    if (Value == null)
                    {
                        Value = codec.valueCodec.Read(new CodedInputStream(ZeroLengthMessageStreamData));
                    }
                }

                public void WriteTo(CodedOutputStream output)
                {
                    codec.keyCodec.WriteTagAndValue(output, Key);
                    codec.valueCodec.WriteTagAndValue(output, Value);
                }

                public int CalculateSize()
                {
                    return codec.keyCodec.CalculateSizeWithTag(Key) + codec.valueCodec.CalculateSizeWithTag(Value);
                }

                MessageDescriptor IMessage.Descriptor { get { return null; } }
            }
        }

        private class MapView<T> : ICollection<T>, ICollection
        {
            private readonly MapField<TKey, TValue> parent;
            private readonly Func<KeyValuePair<TKey, TValue>, T> projection;
            private readonly Func<T, bool> containsCheck;

            internal MapView(
                MapField<TKey, TValue> parent,
                Func<KeyValuePair<TKey, TValue>, T> projection,
                Func<T, bool> containsCheck)
            {
                this.parent = parent;
                this.projection = projection;
                this.containsCheck = containsCheck;
            }

            public int Count { get { return parent.Count; } }

            public bool IsReadOnly { get { return true; } }

            public bool IsSynchronized { get { return false; } }

            public object SyncRoot { get { return parent; } }

            public void Add(T item)
            {
                throw new NotSupportedException();
            }

            public void Clear()
            {
                throw new NotSupportedException();
            }

            public bool Contains(T item)
            {
                return containsCheck(item);
            }

            public void CopyTo(T[] array, int arrayIndex)
            {
                if (arrayIndex < 0)
                {
                    throw new ArgumentOutOfRangeException(nameof(arrayIndex));
                }
                if (arrayIndex + Count > array.Length)
                {
                    throw new ArgumentException("Not enough space in the array", nameof(array));
                }
                foreach (var item in this)
                {
                    array[arrayIndex++] = item;
                }
            }

            public IEnumerator<T> GetEnumerator()
            {
                return parent.list.Select(projection).GetEnumerator();
            }

            public bool Remove(T item)
            {
                throw new NotSupportedException();
            }

            IEnumerator IEnumerable.GetEnumerator()
            {
                return GetEnumerator();
            }

            public void CopyTo(Array array, int index)
            {
                if (index < 0)
                {
                    throw new ArgumentOutOfRangeException(nameof(index));
                }
                if (index + Count > array.Length)
                {
                    throw new ArgumentException("Not enough space in the array", nameof(array));
                }
                foreach (var item in this)
                {
                    array.SetValue(item, index++);
                }
            }
        }
    }
}
