#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 System.IO;
using Google.Protobuf.Reflection;

namespace Google.Protobuf
{
    /// <summary>
    /// Used to keep track of fields which were seen when parsing a protocol message
    /// but whose field numbers or types are unrecognized. This most frequently
    /// occurs when new fields are added to a message type and then messages containing
    /// those fields are read by old software that was built before the new types were
    /// added.
    ///
    /// Most users will never need to use this class directly.
    /// </summary>
    public sealed partial class UnknownFieldSet
    {
        private readonly IDictionary<int, UnknownField> fields;

        /// <summary>
        /// Creates a new UnknownFieldSet.
        /// </summary>
        internal UnknownFieldSet()
        {
            this.fields = new Dictionary<int, UnknownField>();
        }

        /// <summary>
        /// Checks whether or not the given field number is present in the set.
        /// </summary>
        internal bool HasField(int field)
        {
            return fields.ContainsKey(field);
        }

        /// <summary>
        /// Serializes the set and writes it to <paramref name="output"/>.
        /// </summary>
        public void WriteTo(CodedOutputStream output)
        {
            foreach (KeyValuePair<int, UnknownField> entry in fields)
            {
                entry.Value.WriteTo(entry.Key, output);
            }
        }

        /// <summary>
        /// Gets the number of bytes required to encode this set.
        /// </summary>
        public int CalculateSize()
        {
            int result = 0;
            foreach (KeyValuePair<int, UnknownField> entry in fields)
            {
                result += entry.Value.GetSerializedSize(entry.Key);
            }
            return result;
        }

        /// <summary>
        /// Checks if two unknown field sets are equal.
        /// </summary>
        public override bool Equals(object other)
        {
            if (ReferenceEquals(this, other))
            {
                return true;
            }
            UnknownFieldSet otherSet = other as UnknownFieldSet;
            IDictionary<int, UnknownField> otherFields = otherSet.fields;
            if (fields.Count  != otherFields.Count)
            {
                return false;
            }
            foreach (KeyValuePair<int, UnknownField> leftEntry in fields)
            {
                UnknownField rightValue;
                if (!otherFields.TryGetValue(leftEntry.Key, out rightValue))
                {
                    return false;
                }
                if (!leftEntry.Value.Equals(rightValue))
                {
                    return false;
                }
            }
            return true;
        }

        /// <summary>
        /// Gets the unknown field set's hash code.
        /// </summary>
        public override int GetHashCode()
        {
            int ret = 1;
            foreach (KeyValuePair<int, UnknownField> field in fields)
            {
                // Use ^ here to make the field order irrelevant.
                int hash = field.Key.GetHashCode() ^ field.Value.GetHashCode();
                ret ^= hash;
            }
            return ret;
        }

        // Optimization:  We keep around the last field that was
        // modified so that we can efficiently add to it multiple times in a
        // row (important when parsing an unknown repeated field).
        private int lastFieldNumber;
        private UnknownField lastField;

        private UnknownField GetOrAddField(int number)
        {
            if (lastField != null && number == lastFieldNumber)
            {
                return lastField;
            }
            if (number == 0)
            {
                return null;
            }

            UnknownField existing;
            if (fields.TryGetValue(number, out existing))
            {
                return existing;
            }
            lastField = new UnknownField();
            AddOrReplaceField(number, lastField);
            lastFieldNumber = number;
            return lastField;
        }

        /// <summary>
        /// Adds a field to the set. If a field with the same number already exists, it
        /// is replaced.
        /// </summary>
        internal UnknownFieldSet AddOrReplaceField(int number, UnknownField field)
        {
            if (number == 0)
            {
                throw new ArgumentOutOfRangeException("number", "Zero is not a valid field number.");
            }
            fields[number] = field;
            return this;
        }

        /// <summary>
        /// Parse a single field from <paramref name="input"/> and merge it
        /// into this set.
        /// </summary>
        /// <param name="input">The coded input stream containing the field</param>
        /// <returns>false if the tag is an "end group" tag, true otherwise</returns>
        private bool MergeFieldFrom(CodedInputStream input)
        {
            uint tag = input.LastTag;
            int number = WireFormat.GetTagFieldNumber(tag);
            switch (WireFormat.GetTagWireType(tag))
            {
                case WireFormat.WireType.Varint:
                    {
                        ulong uint64 = input.ReadUInt64();
                        GetOrAddField(number).AddVarint(uint64);
                        return true;
                    }
                case WireFormat.WireType.Fixed32:
                    {
                        uint uint32 = input.ReadFixed32();
                        GetOrAddField(number).AddFixed32(uint32);
                        return true;
                    }
                case WireFormat.WireType.Fixed64:
                    {
                        ulong uint64 = input.ReadFixed64();
                        GetOrAddField(number).AddFixed64(uint64);
                        return true;
                    }
                case WireFormat.WireType.LengthDelimited:
                    {
                        ByteString bytes = input.ReadBytes();
                        GetOrAddField(number).AddLengthDelimited(bytes);
                        return true;
                    }
                case WireFormat.WireType.StartGroup:
                    {
                        uint endTag = WireFormat.MakeTag(number, WireFormat.WireType.EndGroup);
                        UnknownFieldSet set = new UnknownFieldSet();
                        while (input.ReadTag() != endTag)
                        {
                            set.MergeFieldFrom(input);
                        }
                        GetOrAddField(number).AddGroup(set);
                        return true;
                    }
                case WireFormat.WireType.EndGroup:
                    {
                        return false;
                    }
                default:
                    throw new InvalidOperationException("Wire Type is invalid.");
            }
        }

        /// <summary>
        /// Create a new UnknownFieldSet if unknownFields is null.
        /// Parse a single field from <paramref name="input"/> and merge it
        /// into unknownFields. If <paramref name="input"/> is configured to discard unknown fields,
        /// <paramref name="unknownFields"/> will be returned as-is and the field will be skipped.
        /// </summary>
        /// <param name="unknownFields">The UnknownFieldSet which need to be merged</param>
        /// <param name="input">The coded input stream containing the field</param>
        /// <returns>The merged UnknownFieldSet</returns>
        public static UnknownFieldSet MergeFieldFrom(UnknownFieldSet unknownFields,
                                                     CodedInputStream input)
        {
            if (input.DiscardUnknownFields)
            {
                input.SkipLastField();
                return unknownFields;
            }
            if (unknownFields == null)
            {
                unknownFields = new UnknownFieldSet();
            }
            if (!unknownFields.MergeFieldFrom(input))
            {
                throw new InvalidProtocolBufferException("Merge an unknown field of end-group tag, indicating that the corresponding start-group was missing."); // match the old code-gen
            }
            return unknownFields;
        }

        /// <summary>
        /// Create a new UnknownFieldSet if unknownFields is null.
        /// Parse a single field from <paramref name="input"/> and merge it
        /// into unknownFields. If <paramref name="input"/> is configured to discard unknown fields,
        /// <paramref name="unknownFields"/> will be returned as-is and the field will be skipped.
        /// </summary>
        /// <param name="unknownFields">The UnknownFieldSet which need to be merged</param>
        /// <param name="input">The coded input stream containing the field</param>
        /// <returns>The merged UnknownFieldSet</returns>
        public static bool MergeFieldFrom(ref UnknownFieldSet unknownFields, CodedInputStream input)
        {
            if (input.DiscardUnknownFields)
            {
                input.SkipLastField();
                return true;
            }
            if (unknownFields == null)
            {
                unknownFields = new UnknownFieldSet();
            }
            return unknownFields.MergeFieldFrom(input);
        }

        /// <summary>
        /// Merges the fields from <paramref name="other"/> into this set.
        /// If a field number exists in both sets, the values in <paramref name="other"/>
        /// will be appended to the values in this set.
        /// </summary>
        private UnknownFieldSet MergeFrom(UnknownFieldSet other)
        {
            if (other != null)
            {
                foreach (KeyValuePair<int, UnknownField> entry in other.fields)
                {
                    MergeField(entry.Key, entry.Value);
                }
            }
            return this;
        }

        /// <summary>
        /// Created a new UnknownFieldSet to <paramref name="unknownFields"/> if
        /// needed and merges the fields from <paramref name="other"/> into the first set.
        /// If a field number exists in both sets, the values in <paramref name="other"/>
        /// will be appended to the values in this set.
        /// </summary>
        public static UnknownFieldSet MergeFrom(UnknownFieldSet unknownFields,
                                                UnknownFieldSet other)
        {
            if (other == null)
            {
                return unknownFields;
            }
            if (unknownFields == null)
            {
                unknownFields = new UnknownFieldSet();
            }
            unknownFields.MergeFrom(other);
            return unknownFields;
        }


        /// <summary>
        /// Adds a field to the unknown field set. If a field with the same
        /// number already exists, the two are merged.
        /// </summary>
        private UnknownFieldSet MergeField(int number, UnknownField field)
        {
            if (number == 0)
            {
                throw new ArgumentOutOfRangeException("number", "Zero is not a valid field number.");
            }
            if (HasField(number))
            {
                GetOrAddField(number).MergeFrom(field);
            }
            else
            {
                AddOrReplaceField(number, field);
            }
            return this;
        }

        /// <summary>
        /// Clone an unknown field set from <paramref name="other"/>.
        /// </summary>
        public static UnknownFieldSet Clone(UnknownFieldSet other)
        {
            if (other == null)
            {
                return null;
            }
            UnknownFieldSet unknownFields = new UnknownFieldSet();
            unknownFields.MergeFrom(other);
            return unknownFields;
        }
    }
}

