#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 System.IO;
using Google.ProtocolBuffers.Descriptors;
using Google.ProtocolBuffers.TestProtos;
using Xunit;

namespace Google.ProtocolBuffers
{
    public class AbstractMessageTest
    {
        [Fact]
        public void Clear()
        {
            AbstractMessageWrapper message =
                new AbstractMessageWrapper.Builder(TestAllTypes.CreateBuilder(TestUtil.GetAllSet())).Clear().Build();
            TestUtil.AssertClear((TestAllTypes) message.WrappedMessage);
        }

        [Fact]
        public void Copy()
        {
            AbstractMessageWrapper message =
                new AbstractMessageWrapper.Builder(TestAllTypes.CreateBuilder()).MergeFrom(TestUtil.GetAllSet()).Build();
            TestUtil.AssertAllFieldsSet((TestAllTypes) message.WrappedMessage);
        }

        [Fact]
        public void CreateAndBuild()
        {
            TestAllTypes.CreateBuilder()
                .Build();
        }

        [Fact]
        public void SerializedSize()
        {
            TestAllTypes message = TestUtil.GetAllSet();
            IMessage abstractMessage = new AbstractMessageWrapper(TestUtil.GetAllSet());

            Assert.Equal(message.SerializedSize, abstractMessage.SerializedSize);
        }

        [Fact]
        public void Serialization()
        {
            IMessage abstractMessage = new AbstractMessageWrapper(TestUtil.GetAllSet());
            TestUtil.AssertAllFieldsSet(TestAllTypes.ParseFrom(abstractMessage.ToByteString()));
            Assert.Equal(TestUtil.GetAllSet().ToByteString(), abstractMessage.ToByteString());
        }

        [Fact]
        public void Parsing()
        {
            IBuilder builder = new AbstractMessageWrapper.Builder(TestAllTypes.CreateBuilder());
            AbstractMessageWrapper message =
                (AbstractMessageWrapper) builder.WeakMergeFrom(TestUtil.GetAllSet().ToByteString()).WeakBuild();
            TestUtil.AssertAllFieldsSet((TestAllTypes) message.WrappedMessage);
        }

        [Fact]
        public void PackedSerialization()
        {
            IMessage abstractMessage = new AbstractMessageWrapper(TestUtil.GetPackedSet());
            TestUtil.AssertPackedFieldsSet(TestPackedTypes.ParseFrom(abstractMessage.ToByteString()));
            Assert.Equal(TestUtil.GetPackedSet().ToByteString(), abstractMessage.ToByteString());
        }

        [Fact]
        public void PackedParsing()
        {
            AbstractMessageWrapper.Builder builder = new AbstractMessageWrapper.Builder(TestPackedTypes.CreateBuilder());
            AbstractMessageWrapper message = builder.MergeFrom(TestUtil.GetPackedSet().ToByteString()).Build();
            TestUtil.AssertPackedFieldsSet((TestPackedTypes)message.WrappedMessage);
        }

        [Fact]
        public void UnpackedParsingOfPackedInput()
        {
            byte[] bytes = TestUtil.GetPackedSet().ToByteArray();
            TestUnpackedTypes message = TestUnpackedTypes.ParseFrom(bytes);
            TestUtil.AssertUnpackedFieldsSet(message);
        }

        [Fact]
        public void PackedParsingOfUnpackedInput()
        {
            byte[] bytes = TestUnpackedTypes.ParseFrom(TestUtil.GetPackedSet().ToByteArray()).ToByteArray();
            TestPackedTypes message = TestPackedTypes.ParseFrom(bytes);
            TestUtil.AssertPackedFieldsSet(message);
        }

        [Fact]
        public void UnpackedParsingOfPackedInputExtensions()
        {
            byte[] bytes = TestUtil.GetPackedSet().ToByteArray();
            ExtensionRegistry registry = ExtensionRegistry.CreateInstance();
            Unittest.RegisterAllExtensions(registry);
            UnittestImport.RegisterAllExtensions(registry);
            TestUnpackedExtensions message = TestUnpackedExtensions.ParseFrom(bytes, registry);
            TestUtil.AssertUnpackedExtensionsSet(message);
        }

        [Fact]
        public void PackedParsingOfUnpackedInputExtensions()
        {
            byte[] bytes = TestUnpackedTypes.ParseFrom(TestUtil.GetPackedSet().ToByteArray()).ToByteArray();
            ExtensionRegistry registry = ExtensionRegistry.CreateInstance();
            Unittest.RegisterAllExtensions(registry);
            TestPackedExtensions message = TestPackedExtensions.ParseFrom(bytes, registry);
            TestUtil.AssertPackedExtensionsSet(message);
        }

        [Fact]
        public void OptimizedForSize()
        {
            // We're mostly only Checking that this class was compiled successfully.
            TestOptimizedForSize message = TestOptimizedForSize.CreateBuilder().SetI(1).Build();
            message = TestOptimizedForSize.ParseFrom(message.ToByteString());
            Assert.Equal(2, message.SerializedSize);
        }

        // -----------------------------------------------------------------
        // Tests for isInitialized().

        private static readonly TestRequired TestRequiredUninitialized = TestRequired.DefaultInstance;

        private static readonly TestRequired TestRequiredInitialized =
            TestRequired.CreateBuilder().SetA(1).SetB(2).SetC(3).Build();

        [Fact]
        public void IsInitialized()
        {
            TestRequired.Builder builder = TestRequired.CreateBuilder();
            AbstractMessageWrapper.Builder abstractBuilder = new AbstractMessageWrapper.Builder(builder);

            Assert.False(abstractBuilder.IsInitialized);
            builder.A = 1;
            Assert.False(abstractBuilder.IsInitialized);
            builder.B = 1;
            Assert.False(abstractBuilder.IsInitialized);
            builder.C = 1;
            Assert.True(abstractBuilder.IsInitialized);
        }

        [Fact]
        public void ForeignIsInitialized()
        {
            TestRequiredForeign.Builder builder = TestRequiredForeign.CreateBuilder();
            AbstractMessageWrapper.Builder abstractBuilder = new AbstractMessageWrapper.Builder(builder);

            Assert.True(abstractBuilder.IsInitialized);

            builder.SetOptionalMessage(TestRequiredUninitialized);
            Assert.False(abstractBuilder.IsInitialized);

            builder.SetOptionalMessage(TestRequiredInitialized);
            Assert.True(abstractBuilder.IsInitialized);

            builder.AddRepeatedMessage(TestRequiredUninitialized);
            Assert.False(abstractBuilder.IsInitialized);

            builder.SetRepeatedMessage(0, TestRequiredInitialized);
            Assert.True(abstractBuilder.IsInitialized);
        }

        // -----------------------------------------------------------------
        // Tests for mergeFrom

        private static readonly TestAllTypes MergeSource = TestAllTypes.CreateBuilder()
            .SetOptionalInt32(1)
            .SetOptionalString("foo")
            .SetOptionalForeignMessage(ForeignMessage.DefaultInstance)
            .AddRepeatedString("bar")
            .Build();

        private static readonly TestAllTypes MergeDest = TestAllTypes.CreateBuilder()
            .SetOptionalInt64(2)
            .SetOptionalString("baz")
            .SetOptionalForeignMessage(ForeignMessage.CreateBuilder().SetC(3).Build())
            .AddRepeatedString("qux")
            .Build();

        private const string MergeResultText = "optional_int32: 1\n" +
                                               "optional_int64: 2\n" +
                                               "optional_string: \"foo\"\n" +
                                               "optional_foreign_message {\n" +
                                               "  c: 3\n" +
                                               "}\n" +
                                               "repeated_string: \"qux\"\n" +
                                               "repeated_string: \"bar\"\n";

        [Fact]
        public void MergeFrom()
        {
            AbstractMessageWrapper result = (AbstractMessageWrapper)
                                            new AbstractMessageWrapper.Builder(TestAllTypes.CreateBuilder(MergeDest))
                                                .MergeFrom(MergeSource)
                                                .Build();

            Assert.Equal(MergeResultText, result.ToString());
        }

        // -----------------------------------------------------------------
        // Tests for equals and hashCode

        [Fact]
        public void EqualsAndHashCode()
        {
            TestAllTypes a = TestUtil.GetAllSet();
            TestAllTypes b = TestAllTypes.CreateBuilder().Build();
            TestAllTypes c = TestAllTypes.CreateBuilder(b).AddRepeatedString("x").Build();
            TestAllTypes d = TestAllTypes.CreateBuilder(c).AddRepeatedString("y").Build();
            TestAllExtensions e = TestUtil.GetAllExtensionsSet();
            TestAllExtensions f = TestAllExtensions.CreateBuilder(e)
                .AddExtension(Unittest.RepeatedInt32Extension, 999).Build();

            CheckEqualsIsConsistent(a);
            CheckEqualsIsConsistent(b);
            CheckEqualsIsConsistent(c);
            CheckEqualsIsConsistent(d);
            CheckEqualsIsConsistent(e);
            CheckEqualsIsConsistent(f);

            CheckNotEqual(a, b);
            CheckNotEqual(a, c);
            CheckNotEqual(a, d);
            CheckNotEqual(a, e);
            CheckNotEqual(a, f);

            CheckNotEqual(b, c);
            CheckNotEqual(b, d);
            CheckNotEqual(b, e);
            CheckNotEqual(b, f);

            CheckNotEqual(c, d);
            CheckNotEqual(c, e);
            CheckNotEqual(c, f);

            CheckNotEqual(d, e);
            CheckNotEqual(d, f);

            CheckNotEqual(e, f);

            // Deserializing into the TestEmptyMessage such that every field is an UnknownFieldSet.Field
            TestEmptyMessage eUnknownFields = TestEmptyMessage.ParseFrom(e.ToByteArray());
            TestEmptyMessage fUnknownFields = TestEmptyMessage.ParseFrom(f.ToByteArray());
            CheckNotEqual(eUnknownFields, fUnknownFields);
            CheckEqualsIsConsistent(eUnknownFields);
            CheckEqualsIsConsistent(fUnknownFields);

            // Subseqent reconstitutions should be identical
            TestEmptyMessage eUnknownFields2 = TestEmptyMessage.ParseFrom(e.ToByteArray());
            CheckEqualsIsConsistent(eUnknownFields, eUnknownFields2);
        }

        /// <summary>
        /// Asserts that the given protos are equal and have the same hash code.
        /// </summary>
        private static void CheckEqualsIsConsistent(IMessage message)
        {
            // Object should be equal to itself.
            Assert.Equal(message, message);

            // Object should be equal to a dynamic copy of itself.
            DynamicMessage dynamic = DynamicMessage.CreateBuilder(message).Build();
            CheckEqualsIsConsistent(message, dynamic);
        }

        /// <summary>
        /// Asserts that the given protos are equal and have the same hash code.
        /// </summary>
        private static void CheckEqualsIsConsistent(IMessage message1, IMessage message2)
        {
            // Not using Assert.AreEqual as that checks for type equality, which isn't
            // what we want bearing in mind the dynamic message checks.
            Assert.True(message1.Equals(message2));
            Assert.True(message2.Equals(message1));
            Assert.Equal(message2.GetHashCode(), message1.GetHashCode());
        }

        /// <summary>
        /// Asserts that the given protos 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. (If this test fails, it's probably still due to a bug.)
        /// </remarks>
        private static void CheckNotEqual(IMessage m1, IMessage m2)
        {
            String equalsError = string.Format("{0} should not be equal to {1}", m1, m2);
            Assert.False(m1.Equals(m2), equalsError);
            Assert.False(m2.Equals(m1), equalsError);

            Assert.False(m1.GetHashCode() == m2.GetHashCode(),
                           string.Format("{0} should have a different hash code from {1}", m1, m2));
        }

        /// <summary>
        /// Extends AbstractMessage and wraps some other message object.  The methods
        /// of the Message interface which aren't explicitly implemented by
        /// AbstractMessage are forwarded to the wrapped object.  This allows us to
        /// test that AbstractMessage's implementations work even if the wrapped
        /// object does not use them.
        /// </summary>
        private class AbstractMessageWrapper : AbstractMessage<AbstractMessageWrapper, AbstractMessageWrapper.Builder>
        {
            private readonly IMessage wrappedMessage;

            public IMessage WrappedMessage
            {
                get { return wrappedMessage; }
            }

            public AbstractMessageWrapper(IMessage wrappedMessage)
            {
                this.wrappedMessage = wrappedMessage;
            }

            public override MessageDescriptor DescriptorForType
            {
                get { return wrappedMessage.DescriptorForType; }
            }

            public override AbstractMessageWrapper DefaultInstanceForType
            {
                get { return new AbstractMessageWrapper(wrappedMessage.WeakDefaultInstanceForType); }
            }

            public override IDictionary<FieldDescriptor, object> AllFields
            {
                get { return wrappedMessage.AllFields; }
            }

            public override bool HasField(FieldDescriptor field)
            {
                return wrappedMessage.HasField(field);
            }

            public override object this[FieldDescriptor field]
            {
                get { return wrappedMessage[field]; }
            }

            public override object this[FieldDescriptor field, int index]
            {
                get { return wrappedMessage[field, index]; }
            }

            public override int GetRepeatedFieldCount(FieldDescriptor field)
            {
                return wrappedMessage.GetRepeatedFieldCount(field);
            }

            public override UnknownFieldSet UnknownFields
            {
                get { return wrappedMessage.UnknownFields; }
            }

            public override Builder CreateBuilderForType()
            {
                return new Builder(wrappedMessage.WeakCreateBuilderForType());
            }

            public override Builder ToBuilder()
            {
                return new Builder(wrappedMessage.WeakToBuilder());
            }

            internal class Builder : AbstractBuilder<AbstractMessageWrapper, Builder>
            {
                private readonly IBuilder wrappedBuilder;

                protected override Builder ThisBuilder
                {
                    get { return this; }
                }

                internal Builder(IBuilder wrappedBuilder)
                {
                    this.wrappedBuilder = wrappedBuilder;
                }

                public override Builder MergeFrom(AbstractMessageWrapper other)
                {
                    wrappedBuilder.WeakMergeFrom(other.wrappedMessage);
                    return this;
                }

                public override bool IsInitialized
                {
                    get { return wrappedBuilder.IsInitialized; }
                }

                public override IDictionary<FieldDescriptor, object> AllFields
                {
                    get { return wrappedBuilder.AllFields; }
                }

                public override object this[FieldDescriptor field]
                {
                    get { return wrappedBuilder[field]; }
                    set { wrappedBuilder[field] = value; }
                }

                public override MessageDescriptor DescriptorForType
                {
                    get { return wrappedBuilder.DescriptorForType; }
                }

                public override int GetRepeatedFieldCount(FieldDescriptor field)
                {
                    return wrappedBuilder.GetRepeatedFieldCount(field);
                }

                public override object this[FieldDescriptor field, int index]
                {
                    get { return wrappedBuilder[field, index]; }
                    set { wrappedBuilder[field, index] = value; }
                }

                public override bool HasField(FieldDescriptor field)
                {
                    return wrappedBuilder.HasField(field);
                }

                public override UnknownFieldSet UnknownFields
                {
                    get { return wrappedBuilder.UnknownFields; }
                    set { wrappedBuilder.UnknownFields = value; }
                }

                public override AbstractMessageWrapper Build()
                {
                    return new AbstractMessageWrapper(wrappedBuilder.WeakBuild());
                }

                public override AbstractMessageWrapper BuildPartial()
                {
                    return new AbstractMessageWrapper(wrappedBuilder.WeakBuildPartial());
                }

                public override Builder Clone()
                {
                    return new Builder(wrappedBuilder.WeakClone());
                }

                public override AbstractMessageWrapper DefaultInstanceForType
                {
                    get { return new AbstractMessageWrapper(wrappedBuilder.WeakDefaultInstanceForType); }
                }

                public override Builder ClearField(FieldDescriptor field)
                {
                    wrappedBuilder.WeakClearField(field);
                    return this;
                }

                public override Builder AddRepeatedField(FieldDescriptor field, object value)
                {
                    wrappedBuilder.WeakAddRepeatedField(field, value);
                    return this;
                }

                public override IBuilder CreateBuilderForField(FieldDescriptor field)
                {
                    wrappedBuilder.CreateBuilderForField(field);
                    return this;
                }

                public override Builder MergeFrom(IMessage other)
                {
                    wrappedBuilder.WeakMergeFrom(other);
                    return this;
                }

                public override Builder MergeFrom(ICodedInputStream input, ExtensionRegistry extensionRegistry)
                {
                    wrappedBuilder.WeakMergeFrom(input, extensionRegistry);
                    return this;
                }
            }
        }
    }
}