﻿#region Copyright notice and license
// Protocol Buffers - Google's data interchange format
// Copyright 2008 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.Collections;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Security;

namespace Google.Protobuf
{
    /// <summary>
    /// Methods for managing <see cref="ExtensionSet{TTarget}"/>s with null checking.
    /// 
    /// Most users will not use this class directly and its API is experimental and subject to change.
    /// </summary>
    public static class ExtensionSet
    {
        private static bool TryGetValue<TTarget>(ref ExtensionSet<TTarget> set, Extension extension, out IExtensionValue value) where TTarget : IExtendableMessage<TTarget>
        {
            if (set == null)
            {
                value = null;
                return false;
            }
            return set.ValuesByNumber.TryGetValue(extension.FieldNumber, out value);
        }

        /// <summary>
        /// Gets the value of the specified extension
        /// </summary>
        public static TValue Get<TTarget, TValue>(ref ExtensionSet<TTarget> set, Extension<TTarget, TValue> extension) where TTarget : IExtendableMessage<TTarget>
        {
            IExtensionValue value;
            if (TryGetValue(ref set, extension, out value))
            {
                return ((ExtensionValue<TValue>)value).GetValue();
            }
            else 
            {
                return extension.DefaultValue;
            }
        }

        /// <summary>
        /// Gets the value of the specified repeated extension or null if it doesn't exist in this set
        /// </summary>
        public static RepeatedField<TValue> Get<TTarget, TValue>(ref ExtensionSet<TTarget> set, RepeatedExtension<TTarget, TValue> extension) where TTarget : IExtendableMessage<TTarget>
        {
            IExtensionValue value;
            if (TryGetValue(ref set, extension, out value))
            {
                return ((RepeatedExtensionValue<TValue>)value).GetValue();
            }
            else 
            {
                return null;
            }
        }

        /// <summary>
        /// Gets the value of the specified repeated extension, registering it if it doesn't exist
        /// </summary>
        public static RepeatedField<TValue> GetOrInitialize<TTarget, TValue>(ref ExtensionSet<TTarget> set, RepeatedExtension<TTarget, TValue> extension) where TTarget : IExtendableMessage<TTarget>
        {
            IExtensionValue value;
            if (set == null)
            {
                value = extension.CreateValue();
                set = new ExtensionSet<TTarget>();
                set.ValuesByNumber.Add(extension.FieldNumber, value);
            }
            else
            {
                if (!set.ValuesByNumber.TryGetValue(extension.FieldNumber, out value))
                {
                    value = extension.CreateValue();
                    set.ValuesByNumber.Add(extension.FieldNumber, value);
                }
            }

            return ((RepeatedExtensionValue<TValue>)value).GetValue();
        }

        /// <summary>
        /// Sets the value of the specified extension. This will make a new instance of ExtensionSet if the set is null.
        /// </summary>
        public static void Set<TTarget, TValue>(ref ExtensionSet<TTarget> set, Extension<TTarget, TValue> extension, TValue value) where TTarget : IExtendableMessage<TTarget>
        {
            ProtoPreconditions.CheckNotNullUnconstrained(value, nameof(value));

            IExtensionValue extensionValue;
            if (set == null)
            {
                extensionValue = extension.CreateValue();
                set = new ExtensionSet<TTarget>();
                set.ValuesByNumber.Add(extension.FieldNumber, extensionValue);
            }
            else
            {
                if (!set.ValuesByNumber.TryGetValue(extension.FieldNumber, out extensionValue))
                {
                    extensionValue = extension.CreateValue();
                    set.ValuesByNumber.Add(extension.FieldNumber, extensionValue);
                }
            }
            
            ((ExtensionValue<TValue>)extensionValue).SetValue(value);
        }

        /// <summary>
        /// Gets whether the value of the specified extension is set
        /// </summary>
        public static bool Has<TTarget, TValue>(ref ExtensionSet<TTarget> set, Extension<TTarget, TValue> extension) where TTarget : IExtendableMessage<TTarget>
        {
            IExtensionValue value;
            return TryGetValue(ref set, extension, out value);
        }

        /// <summary>
        /// Clears the value of the specified extension
        /// </summary>
        public static void Clear<TTarget, TValue>(ref ExtensionSet<TTarget> set, Extension<TTarget, TValue> extension) where TTarget : IExtendableMessage<TTarget>
        {
            if (set == null)
            {
                return;
            }
            set.ValuesByNumber.Remove(extension.FieldNumber);
            if (set.ValuesByNumber.Count == 0)
            {
                set = null;
            }
        }

        /// <summary>
        /// Clears the value of the specified extension
        /// </summary>
        public static void Clear<TTarget, TValue>(ref ExtensionSet<TTarget> set, RepeatedExtension<TTarget, TValue> extension) where TTarget : IExtendableMessage<TTarget>
        {
            if (set == null)
            {
                return;
            }
            set.ValuesByNumber.Remove(extension.FieldNumber);
            if (set.ValuesByNumber.Count == 0)
            {
                set = null;
            }
        }

        /// <summary>
        /// Tries to merge a field from the coded input, returning true if the field was merged.
        /// If the set is null or the field was not otherwise merged, this returns false.
        /// </summary>
        public static bool TryMergeFieldFrom<TTarget>(ref ExtensionSet<TTarget> set, CodedInputStream stream) where TTarget : IExtendableMessage<TTarget>
        {
            ParseContext.Initialize(stream, out ParseContext ctx);
            try
            {
                return TryMergeFieldFrom<TTarget>(ref set, ref ctx);
            }
            finally
            {
                ctx.CopyStateTo(stream);
            }
        }

        /// <summary>
        /// Tries to merge a field from the coded input, returning true if the field was merged.
        /// If the set is null or the field was not otherwise merged, this returns false.
        /// </summary>
        public static bool TryMergeFieldFrom<TTarget>(ref ExtensionSet<TTarget> set, ref ParseContext ctx) where TTarget : IExtendableMessage<TTarget>
        {
            Extension extension;
            int lastFieldNumber = WireFormat.GetTagFieldNumber(ctx.LastTag);

            IExtensionValue extensionValue;
            if (set != null && set.ValuesByNumber.TryGetValue(lastFieldNumber, out extensionValue))
            {
                extensionValue.MergeFrom(ref ctx);
                return true;
            }
            else if (ctx.ExtensionRegistry != null && ctx.ExtensionRegistry.ContainsInputField(ctx.LastTag, typeof(TTarget), out extension))
            {
                IExtensionValue value = extension.CreateValue();
                value.MergeFrom(ref ctx);
                set = (set ?? new ExtensionSet<TTarget>());
                set.ValuesByNumber.Add(extension.FieldNumber, value);
                return true;
            }
            else
            {
                return false;
            }
        }

        /// <summary>
        /// Merges the second set into the first set, creating a new instance if first is null
        /// </summary>
        public static void MergeFrom<TTarget>(ref ExtensionSet<TTarget> first, ExtensionSet<TTarget> second) where TTarget : IExtendableMessage<TTarget>
        {
            if (second == null)
            {
                return;
            }
            if (first == null)
            {
                first = new ExtensionSet<TTarget>();
            }
            foreach (var pair in second.ValuesByNumber)
            {
                IExtensionValue value;
                if (first.ValuesByNumber.TryGetValue(pair.Key, out value))
                {
                    value.MergeFrom(pair.Value);
                }
                else
                {
                    var cloned = pair.Value.Clone();
                    first.ValuesByNumber[pair.Key] = cloned;
                }
            }
        }

        /// <summary>
        /// Clones the set into a new set. If the set is null, this returns null
        /// </summary>
        public static ExtensionSet<TTarget> Clone<TTarget>(ExtensionSet<TTarget> set) where TTarget : IExtendableMessage<TTarget>
        {
            if (set == null)
            {
                return null;
            }

            var newSet = new ExtensionSet<TTarget>();
            foreach (var pair in set.ValuesByNumber)
            {
                var cloned = pair.Value.Clone();
                newSet.ValuesByNumber[pair.Key] = cloned;
            }
            return newSet;
        }
    }

    /// <summary>
    /// Used for keeping track of extensions in messages. 
    /// <see cref="IExtendableMessage{T}"/> methods route to this set.
    /// 
    /// Most users will not need to use this class directly
    /// </summary>
    /// <typeparam name="TTarget">The message type that extensions in this set target</typeparam>
    public sealed class ExtensionSet<TTarget> where TTarget : IExtendableMessage<TTarget>
    {
        internal Dictionary<int, IExtensionValue> ValuesByNumber { get; } = new Dictionary<int, IExtensionValue>();

        /// <summary>
        /// Gets a hash code of the set
        /// </summary>
        public override int GetHashCode()
        {
            int ret = typeof(TTarget).GetHashCode();
            foreach (KeyValuePair<int, IExtensionValue> field in ValuesByNumber)
            {
                // Use ^ here to make the field order irrelevant.
                int hash = field.Key.GetHashCode() ^ field.Value.GetHashCode();
                ret ^= hash;
            }
            return ret;
        }

        /// <summary>
        /// Returns whether this set is equal to the other object
        /// </summary>
        public override bool Equals(object other)
        {
            if (ReferenceEquals(this, other))
            {
                return true;
            }
            ExtensionSet<TTarget> otherSet = other as ExtensionSet<TTarget>;
            if (ValuesByNumber.Count != otherSet.ValuesByNumber.Count)
            {
                return false;
            }
            foreach (var pair in ValuesByNumber)
            {
                IExtensionValue secondValue;
                if (!otherSet.ValuesByNumber.TryGetValue(pair.Key, out secondValue))
                {
                    return false;
                }
                if (!pair.Value.Equals(secondValue))
                {
                    return false;
                }
            }
            return true;
        }

        /// <summary>
        /// Calculates the size of this extension set
        /// </summary>
        public int CalculateSize()
        {
            int size = 0;
            foreach (var value in ValuesByNumber.Values)
            {
                size += value.CalculateSize();
            }
            return size;
        }

        /// <summary>
        /// Writes the extension values in this set to the output stream
        /// </summary>
        public void WriteTo(CodedOutputStream stream)
        {
            
            WriteContext.Initialize(stream, out WriteContext ctx);
            try
            {
                WriteTo(ref ctx);
            }
            finally
            {
                ctx.CopyStateTo(stream);
            }
        }

        /// <summary>
        /// Writes the extension values in this set to the write context
        /// </summary>
        [SecuritySafeCritical]
        public void WriteTo(ref WriteContext ctx)
        {
            foreach (var value in ValuesByNumber.Values)
            {
                value.WriteTo(ref ctx);
            }
        }

        internal bool IsInitialized()
        {
            return ValuesByNumber.Values.All(v => v.IsInitialized());
        }
    }
}
