#region Copyright notice and license

// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc.  All rights reserved.
// http://github.com/jskeet/dotnet-protobufs/
// Original C++/Java/Python code:
// http://code.google.com/p/protobuf/
//
// 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.ProtocolBuffers.Descriptors;
using Google.ProtocolBuffers.TestProtos;
using NUnit.Framework;

namespace Google.ProtocolBuffers
{
    public class UnknownFieldSetTest
    {
        private readonly MessageDescriptor descriptor;
        private readonly TestAllTypes allFields;
        private readonly ByteString allFieldsData;

        /// <summary>
        /// An empty message that has been parsed from allFieldsData.  So, it has
        /// unknown fields of every type.
        /// </summary>
        private readonly TestEmptyMessage emptyMessage;

        private readonly UnknownFieldSet unknownFields;

        public UnknownFieldSetTest()
        {
            descriptor = TestAllTypes.Descriptor;
            allFields = TestUtil.GetAllSet();
            allFieldsData = allFields.ToByteString();
            emptyMessage = TestEmptyMessage.ParseFrom(allFieldsData);
            unknownFields = emptyMessage.UnknownFields;
        }

        private UnknownField GetField(String name)
        {
            FieldDescriptor field = descriptor.FindDescriptor<FieldDescriptor>(name);
            Assert.NotNull(field);
            return unknownFields.FieldDictionary[field.FieldNumber];
        }

        /// <summary>
        /// Constructs a protocol buffer which contains fields with all the same
        /// numbers as allFieldsData except that each field is some other wire
        /// type.
        /// </summary>
        private ByteString GetBizarroData()
        {
            UnknownFieldSet.Builder bizarroFields = UnknownFieldSet.CreateBuilder();

            UnknownField varintField = UnknownField.CreateBuilder().AddVarint(1).Build();
            UnknownField fixed32Field = UnknownField.CreateBuilder().AddFixed32(1).Build();

            foreach (KeyValuePair<int, UnknownField> entry in unknownFields.FieldDictionary)
            {
                if (entry.Value.VarintList.Count == 0)
                {
                    // Original field is not a varint, so use a varint.
                    bizarroFields.AddField(entry.Key, varintField);
                }
                else
                {
                    // Original field *is* a varint, so use something else.
                    bizarroFields.AddField(entry.Key, fixed32Field);
                }
            }

            return bizarroFields.Build().ToByteString();
        }

        // =================================================================

        [Test]
        public void Varint()
        {
            UnknownField field = GetField("optional_int32");
            Assert.AreEqual(1, field.VarintList.Count);
            Assert.AreEqual(allFields.OptionalInt32, (long) field.VarintList[0]);
        }

        [Test]
        public void Fixed32()
        {
            UnknownField field = GetField("optional_fixed32");
            Assert.AreEqual(1, field.Fixed32List.Count);
            Assert.AreEqual(allFields.OptionalFixed32, (int) field.Fixed32List[0]);
        }

        [Test]
        public void Fixed64()
        {
            UnknownField field = GetField("optional_fixed64");
            Assert.AreEqual(1, field.Fixed64List.Count);
            Assert.AreEqual((long)allFields.OptionalFixed64, (long)field.Fixed64List[0]);
        }

        [Test]
        public void LengthDelimited()
        {
            UnknownField field = GetField("optional_bytes");
            Assert.AreEqual(1, field.LengthDelimitedList.Count);
            Assert.AreEqual(allFields.OptionalBytes, field.LengthDelimitedList[0]);
        }

        [Test]
        public void Group()
        {
            FieldDescriptor nestedFieldDescriptor =
                TestAllTypes.Types.OptionalGroup.Descriptor.FindDescriptor<FieldDescriptor>("a");
            Assert.NotNull(nestedFieldDescriptor);

            UnknownField field = GetField("optionalgroup");
            Assert.AreEqual(1, field.GroupList.Count);

            UnknownFieldSet group = field.GroupList[0];
            Assert.AreEqual(1, group.FieldDictionary.Count);
            Assert.IsTrue(group.HasField(nestedFieldDescriptor.FieldNumber));

            UnknownField nestedField = group[nestedFieldDescriptor.FieldNumber];
            Assert.AreEqual(1, nestedField.VarintList.Count);
            Assert.AreEqual(allFields.OptionalGroup.A, (long) nestedField.VarintList[0]);
        }

        [Test]
        public void Serialize()
        {
            // Check that serializing the UnknownFieldSet produces the original data again.
            ByteString data = emptyMessage.ToByteString();
            Assert.AreEqual(allFieldsData, data);
        }

        [Test]
        public void CopyFrom()
        {
            TestEmptyMessage message =
                TestEmptyMessage.CreateBuilder().MergeFrom(emptyMessage).Build();

            Assert.AreEqual(emptyMessage.ToString(), message.ToString());
        }

        [Test]
        public void MergeFrom()
        {
            TestEmptyMessage source =
                TestEmptyMessage.CreateBuilder()
                    .SetUnknownFields(
                        UnknownFieldSet.CreateBuilder()
                            .AddField(2,
                                      UnknownField.CreateBuilder()
                                          .AddVarint(2).Build())
                            .AddField(3,
                                      UnknownField.CreateBuilder()
                                          .AddVarint(4).Build())
                            .Build())
                    .Build();
            TestEmptyMessage destination =
                TestEmptyMessage.CreateBuilder()
                    .SetUnknownFields(
                        UnknownFieldSet.CreateBuilder()
                            .AddField(1,
                                      UnknownField.CreateBuilder()
                                          .AddVarint(1).Build())
                            .AddField(3,
                                      UnknownField.CreateBuilder()
                                          .AddVarint(3).Build())
                            .Build())
                    .MergeFrom(source)
                    .Build();

            Assert.AreEqual(
                "1: 1\n" +
                "2: 2\n" +
                "3: 3\n" +
                "3: 4\n",
                destination.ToString());
        }

        [Test]
        public void Clear()
        {
            UnknownFieldSet fields =
                UnknownFieldSet.CreateBuilder().MergeFrom(unknownFields).Clear().Build();
            Assert.AreEqual(0, fields.FieldDictionary.Count);
        }

        [Test]
        public void ClearMessage()
        {
            TestEmptyMessage message =
                TestEmptyMessage.CreateBuilder().MergeFrom(emptyMessage).Clear().Build();
            Assert.AreEqual(0, message.SerializedSize);
        }

        [Test]
        public void ParseKnownAndUnknown()
        {
            // Test mixing known and unknown fields when parsing.

            UnknownFieldSet fields =
                UnknownFieldSet.CreateBuilder(unknownFields)
                    .AddField(123456,
                              UnknownField.CreateBuilder().AddVarint(654321).Build())
                    .Build();

            ByteString data = fields.ToByteString();
            TestAllTypes destination = TestAllTypes.ParseFrom(data);

            TestUtil.AssertAllFieldsSet(destination);
            Assert.AreEqual(1, destination.UnknownFields.FieldDictionary.Count);

            UnknownField field = destination.UnknownFields[123456];
            Assert.AreEqual(1, field.VarintList.Count);
            Assert.AreEqual(654321, (long) field.VarintList[0]);
        }

        [Test]
        public void WrongTypeTreatedAsUnknown()
        {
            // Test that fields of the wrong wire type are treated like unknown fields
            // when parsing.

            ByteString bizarroData = GetBizarroData();
            TestAllTypes allTypesMessage = TestAllTypes.ParseFrom(bizarroData);
            TestEmptyMessage emptyMessage = TestEmptyMessage.ParseFrom(bizarroData);

            // All fields should have been interpreted as unknown, so the debug strings
            // should be the same.
            Assert.AreEqual(emptyMessage.ToString(), allTypesMessage.ToString());
        }

        [Test]
        public void UnknownExtensions()
        {
            // Make sure fields are properly parsed to the UnknownFieldSet even when
            // they are declared as extension numbers.

            TestEmptyMessageWithExtensions message =
                TestEmptyMessageWithExtensions.ParseFrom(allFieldsData);

            Assert.AreEqual(unknownFields.FieldDictionary.Count,
                            message.UnknownFields.FieldDictionary.Count);
            Assert.AreEqual(allFieldsData, message.ToByteString());
        }

        [Test]
        public void WrongExtensionTypeTreatedAsUnknown()
        {
            // Test that fields of the wrong wire type are treated like unknown fields
            // when parsing extensions.

            ByteString bizarroData = GetBizarroData();
            TestAllExtensions allExtensionsMessage = TestAllExtensions.ParseFrom(bizarroData);
            TestEmptyMessage emptyMessage = TestEmptyMessage.ParseFrom(bizarroData);

            // All fields should have been interpreted as unknown, so the debug strings
            // should be the same.
            Assert.AreEqual(emptyMessage.ToString(),
                            allExtensionsMessage.ToString());
        }

        [Test]
        public void ParseUnknownEnumValue()
        {
            FieldDescriptor singularField =
                TestAllTypes.Descriptor.FindDescriptor<FieldDescriptor>("optional_nested_enum");
            FieldDescriptor repeatedField =
                TestAllTypes.Descriptor.FindDescriptor<FieldDescriptor>("repeated_nested_enum");
            Assert.NotNull(singularField);
            Assert.NotNull(repeatedField);

            ByteString data =
                UnknownFieldSet.CreateBuilder()
                    .AddField(singularField.FieldNumber,
                              UnknownField.CreateBuilder()
                                  .AddVarint((int) TestAllTypes.Types.NestedEnum.BAR)
                                  .AddVarint(5) // not valid
                                  .Build())
                    .AddField(repeatedField.FieldNumber,
                              UnknownField.CreateBuilder()
                                  .AddVarint((int) TestAllTypes.Types.NestedEnum.FOO)
                                  .AddVarint(4) // not valid
                                  .AddVarint((int) TestAllTypes.Types.NestedEnum.BAZ)
                                  .AddVarint(6) // not valid
                                  .Build())
                    .Build()
                    .ToByteString();

            {
                TestAllTypes message = TestAllTypes.ParseFrom(data);
                Assert.AreEqual(TestAllTypes.Types.NestedEnum.BAR,
                                message.OptionalNestedEnum);
                TestUtil.AssertEqual(new[] {TestAllTypes.Types.NestedEnum.FOO, TestAllTypes.Types.NestedEnum.BAZ},
                                     message.RepeatedNestedEnumList);
                TestUtil.AssertEqual(new[] {5UL}, message.UnknownFields[singularField.FieldNumber].VarintList);
                TestUtil.AssertEqual(new[] {4UL, 6UL}, message.UnknownFields[repeatedField.FieldNumber].VarintList);
            }

            {
                TestAllExtensions message =
                    TestAllExtensions.ParseFrom(data, TestUtil.CreateExtensionRegistry());
                Assert.AreEqual(TestAllTypes.Types.NestedEnum.BAR,
                                message.GetExtension(Unittest.OptionalNestedEnumExtension));
                TestUtil.AssertEqual(new[] {TestAllTypes.Types.NestedEnum.FOO, TestAllTypes.Types.NestedEnum.BAZ},
                                     message.GetExtension(Unittest.RepeatedNestedEnumExtension));
                TestUtil.AssertEqual(new[] {5UL}, message.UnknownFields[singularField.FieldNumber].VarintList);
                TestUtil.AssertEqual(new[] {4UL, 6UL}, message.UnknownFields[repeatedField.FieldNumber].VarintList);
            }
        }

        [Test]
        public void LargeVarint()
        {
            ByteString data =
                UnknownFieldSet.CreateBuilder()
                    .AddField(1,
                              UnknownField.CreateBuilder()
                                  .AddVarint(0x7FFFFFFFFFFFFFFFL)
                                  .Build())
                    .Build()
                    .ToByteString();
            UnknownFieldSet parsed = UnknownFieldSet.ParseFrom(data);
            UnknownField field = parsed[1];
            Assert.AreEqual(1, field.VarintList.Count);
            Assert.AreEqual(0x7FFFFFFFFFFFFFFFUL, field.VarintList[0]);
        }

        [Test]
        public void EqualsAndHashCode()
        {
            UnknownField fixed32Field = UnknownField.CreateBuilder().AddFixed32(1).Build();
            UnknownField fixed64Field = UnknownField.CreateBuilder().AddFixed64(1).Build();
            UnknownField varIntField = UnknownField.CreateBuilder().AddVarint(1).Build();
            UnknownField lengthDelimitedField =
                UnknownField.CreateBuilder().AddLengthDelimited(ByteString.Empty).Build();
            UnknownField groupField = UnknownField.CreateBuilder().AddGroup(unknownFields).Build();

            UnknownFieldSet a = UnknownFieldSet.CreateBuilder().AddField(1, fixed32Field).Build();
            UnknownFieldSet b = UnknownFieldSet.CreateBuilder().AddField(1, fixed64Field).Build();
            UnknownFieldSet c = UnknownFieldSet.CreateBuilder().AddField(1, varIntField).Build();
            UnknownFieldSet d = UnknownFieldSet.CreateBuilder().AddField(1, lengthDelimitedField).Build();
            UnknownFieldSet e = UnknownFieldSet.CreateBuilder().AddField(1, groupField).Build();

            CheckEqualsIsConsistent(a);
            CheckEqualsIsConsistent(b);
            CheckEqualsIsConsistent(c);
            CheckEqualsIsConsistent(d);
            CheckEqualsIsConsistent(e);

            CheckNotEqual(a, b);
            CheckNotEqual(a, c);
            CheckNotEqual(a, d);
            CheckNotEqual(a, e);
            CheckNotEqual(b, c);
            CheckNotEqual(b, d);
            CheckNotEqual(b, e);
            CheckNotEqual(c, d);
            CheckNotEqual(c, e);
            CheckNotEqual(d, e);
        }

        /// <summary>
        /// Asserts that the given field sets are not equal and have different
        /// hash codes.
        /// </summary>
        /// <remarks>
        /// It's valid for non-equal objects to have the same hash code, so
        /// this test is stricter than it needs to be. However, this should happen
        /// relatively rarely.
        /// </remarks>
        /// <param name="s1"></param>
        /// <param name="s2"></param>
        private static void CheckNotEqual(UnknownFieldSet s1, UnknownFieldSet s2)
        {
            String equalsError = string.Format("{0} should not be equal to {1}", s1, s2);
            Assert.IsFalse(s1.Equals(s2), equalsError);
            Assert.IsFalse(s2.Equals(s1), equalsError);

            Assert.IsFalse(s1.GetHashCode() == s2.GetHashCode(),
                           string.Format("{0} should have a different hash code from {1}", s1, s2));
        }

        /**
     * Asserts that the given field sets are equal and have identical hash codes.
     */

        private static void CheckEqualsIsConsistent(UnknownFieldSet set)
        {
            // Object should be equal to itself.
            Assert.AreEqual(set, set);

            // Object should be equal to a copy of itself.
            UnknownFieldSet copy = UnknownFieldSet.CreateBuilder(set).Build();
            Assert.AreEqual(set, copy);
            Assert.AreEqual(copy, set);
            Assert.AreEqual(set.GetHashCode(), copy.GetHashCode());
        }
    }
}