#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 Xunit;

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();
        }

        // =================================================================

        [Fact]
        public void Varint()
        {
            UnknownField field = GetField("optional_int32");
            Assert.Equal(1, field.VarintList.Count);
            Assert.Equal(allFields.OptionalInt32, (long) field.VarintList[0]);
        }

        [Fact]
        public void Fixed32()
        {
            UnknownField field = GetField("optional_fixed32");
            Assert.Equal(1, field.Fixed32List.Count);
            Assert.Equal<long>(allFields.OptionalFixed32, (int) field.Fixed32List[0]);
        }

        [Fact]
        public void Fixed64()
        {
            UnknownField field = GetField("optional_fixed64");
            Assert.Equal(1, field.Fixed64List.Count);
            Assert.Equal((long)allFields.OptionalFixed64, (long)field.Fixed64List[0]);
        }

        [Fact]
        public void LengthDelimited()
        {
            UnknownField field = GetField("optional_bytes");
            Assert.Equal(1, field.LengthDelimitedList.Count);
            Assert.Equal(allFields.OptionalBytes, field.LengthDelimitedList[0]);
        }

        [Fact]
        public void Group()
        {
            FieldDescriptor nestedFieldDescriptor =
                TestAllTypes.Types.OptionalGroup.Descriptor.FindDescriptor<FieldDescriptor>("a");
            Assert.NotNull(nestedFieldDescriptor);

            UnknownField field = GetField("optionalgroup");
            Assert.Equal(1, field.GroupList.Count);

            UnknownFieldSet group = field.GroupList[0];
            Assert.Equal(1, group.FieldDictionary.Count);
            Assert.True(group.HasField(nestedFieldDescriptor.FieldNumber));

            UnknownField nestedField = group[nestedFieldDescriptor.FieldNumber];
            Assert.Equal(1, nestedField.VarintList.Count);
            Assert.Equal(allFields.OptionalGroup.A, (long) nestedField.VarintList[0]);
        }

        [Fact]
        public void Serialize()
        {
            // Check that serializing the UnknownFieldSet produces the original data again.
            ByteString data = emptyMessage.ToByteString();
            Assert.Equal(allFieldsData, data);
        }

        [Fact]
        public void CopyFrom()
        {
            TestEmptyMessage message =
                TestEmptyMessage.CreateBuilder().MergeFrom(emptyMessage).Build();

            Assert.Equal(emptyMessage.ToString(), message.ToString());
        }

        [Fact]
        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.Equal(
                "1: 1\n" +
                "2: 2\n" +
                "3: 3\n" +
                "3: 4\n",
                destination.ToString());
        }

        [Fact]
        public void Clear()
        {
            UnknownFieldSet fields =
                UnknownFieldSet.CreateBuilder().MergeFrom(unknownFields).Clear().Build();
            Assert.Equal(0, fields.FieldDictionary.Count);
        }

        [Fact]
        public void ClearMessage()
        {
            TestEmptyMessage message =
                TestEmptyMessage.CreateBuilder().MergeFrom(emptyMessage).Clear().Build();
            Assert.Equal(0, message.SerializedSize);
        }

        [Fact]
        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.Equal(1, destination.UnknownFields.FieldDictionary.Count);

            UnknownField field = destination.UnknownFields[123456];
            Assert.Equal(1, field.VarintList.Count);
            Assert.Equal(654321, (long) field.VarintList[0]);
        }

        [Fact]
        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.Equal(emptyMessage.ToString(), allTypesMessage.ToString());
        }

        [Fact]
        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.Equal(unknownFields.FieldDictionary.Count,
                            message.UnknownFields.FieldDictionary.Count);
            Assert.Equal(allFieldsData, message.ToByteString());
        }

        [Fact]
        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.Equal(emptyMessage.ToString(),
                            allExtensionsMessage.ToString());
        }

        [Fact]
        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.Equal(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.Equal(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);
            }
        }

        [Fact]
        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.Equal(1, field.VarintList.Count);
            Assert.Equal(0x7FFFFFFFFFFFFFFFUL, field.VarintList[0]);
        }

        [Fact]
        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.False(s1.Equals(s2), equalsError);
            Assert.False(s2.Equals(s1), equalsError);

            Assert.False(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.Equal(set, set);

            // Object should be equal to a copy of itself.
            UnknownFieldSet copy = UnknownFieldSet.CreateBuilder(set).Build();
            Assert.Equal(set, copy);
            Assert.Equal(copy, set);
            Assert.Equal(set.GetHashCode(), copy.GetHashCode());
        }
    }
}