#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 NUnit.Framework;

namespace Google.ProtocolBuffers
{
    public class AbstractMessageTest
    {
        [Test]
        public void Clear()
        {
            AbstractMessageWrapper message =
                new AbstractMessageWrapper.Builder(TestAllTypes.CreateBuilder(TestUtil.GetAllSet())).Clear().Build();
            TestUtil.AssertClear((TestAllTypes) message.WrappedMessage);
        }

        [Test]
        public void Copy()
        {
            AbstractMessageWrapper message =
                new AbstractMessageWrapper.Builder(TestAllTypes.CreateBuilder()).MergeFrom(TestUtil.GetAllSet()).Build();
            TestUtil.AssertAllFieldsSet((TestAllTypes) message.WrappedMessage);
        }

        [Test]
        public void CreateAndBuild()
        {
            TestAllTypes.CreateBuilder()
                .Build();
        }

        [Test]
        public void SerializedSize()
        {
            TestAllTypes message = TestUtil.GetAllSet();
            IMessage abstractMessage = new AbstractMessageWrapper(TestUtil.GetAllSet());

            Assert.AreEqual(message.SerializedSize, abstractMessage.SerializedSize);
        }

        [Test]
        public void Serialization()
        {
            IMessage abstractMessage = new AbstractMessageWrapper(TestUtil.GetAllSet());
            TestUtil.AssertAllFieldsSet(TestAllTypes.ParseFrom(abstractMessage.ToByteString()));
            Assert.AreEqual(TestUtil.GetAllSet().ToByteString(), abstractMessage.ToByteString());
        }

        [Test]
        public void Parsing()
        {
            IBuilder builder = new AbstractMessageWrapper.Builder(TestAllTypes.CreateBuilder());
            AbstractMessageWrapper message =
                (AbstractMessageWrapper) builder.WeakMergeFrom(TestUtil.GetAllSet().ToByteString()).WeakBuild();
            TestUtil.AssertAllFieldsSet((TestAllTypes) message.WrappedMessage);
        }

        [Test]
        public void PackedSerialization()
        {
            IMessage abstractMessage = new AbstractMessageWrapper(TestUtil.GetPackedSet());
            TestUtil.AssertPackedFieldsSet(TestPackedTypes.ParseFrom(abstractMessage.ToByteString()));
            Assert.AreEqual(TestUtil.GetPackedSet().ToByteString(), abstractMessage.ToByteString());
        }

        [Test]
        public void PackedParsing()
        {
            AbstractMessageWrapper.Builder builder = new AbstractMessageWrapper.Builder(TestPackedTypes.CreateBuilder());
            AbstractMessageWrapper message = builder.MergeFrom(TestUtil.GetPackedSet().ToByteString()).Build();
            TestUtil.AssertPackedFieldsSet((TestPackedTypes)message.WrappedMessage);
        }

        [Test]
        public void UnpackedParsingOfPackedInput()
        {
            byte[] bytes = TestUtil.GetPackedSet().ToByteArray();
            TestUnpackedTypes message = TestUnpackedTypes.ParseFrom(bytes);
            TestUtil.AssertUnpackedFieldsSet(message);
        }

        [Test]
        public void PackedParsingOfUnpackedInput()
        {
            byte[] bytes = TestUnpackedTypes.ParseFrom(TestUtil.GetPackedSet().ToByteArray()).ToByteArray();
            TestPackedTypes message = TestPackedTypes.ParseFrom(bytes);
            TestUtil.AssertPackedFieldsSet(message);
        }

        [Test]
        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);
        }

        [Test]
        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);
        }

        [Test]
        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.AreEqual(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();

        [Test]
        public void IsInitialized()
        {
            TestRequired.Builder builder = TestRequired.CreateBuilder();
            AbstractMessageWrapper.Builder abstractBuilder = new AbstractMessageWrapper.Builder(builder);

            Assert.IsFalse(abstractBuilder.IsInitialized);
            builder.A = 1;
            Assert.IsFalse(abstractBuilder.IsInitialized);
            builder.B = 1;
            Assert.IsFalse(abstractBuilder.IsInitialized);
            builder.C = 1;
            Assert.IsTrue(abstractBuilder.IsInitialized);
        }

        [Test]
        public void ForeignIsInitialized()
        {
            TestRequiredForeign.Builder builder = TestRequiredForeign.CreateBuilder();
            AbstractMessageWrapper.Builder abstractBuilder = new AbstractMessageWrapper.Builder(builder);

            Assert.IsTrue(abstractBuilder.IsInitialized);

            builder.SetOptionalMessage(TestRequiredUninitialized);
            Assert.IsFalse(abstractBuilder.IsInitialized);

            builder.SetOptionalMessage(TestRequiredInitialized);
            Assert.IsTrue(abstractBuilder.IsInitialized);

            builder.AddRepeatedMessage(TestRequiredUninitialized);
            Assert.IsFalse(abstractBuilder.IsInitialized);

            builder.SetRepeatedMessage(0, TestRequiredInitialized);
            Assert.IsTrue(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";

        [Test]
        public void MergeFrom()
        {
            AbstractMessageWrapper result = (AbstractMessageWrapper)
                                            new AbstractMessageWrapper.Builder(TestAllTypes.CreateBuilder(MergeDest))
                                                .MergeFrom(MergeSource)
                                                .Build();

            Assert.AreEqual(MergeResultText, result.ToString());
        }

        // -----------------------------------------------------------------
        // Tests for equals and hashCode

        [Test]
        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.AreEqual(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.IsTrue(message1.Equals(message2));
            Assert.IsTrue(message2.Equals(message1));
            Assert.AreEqual(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.IsFalse(m1.Equals(m2), equalsError);
            Assert.IsFalse(m2.Equals(m1), equalsError);

            Assert.IsFalse(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;
                }
            }
        }
    }
}