#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.IO;
using Google.ProtocolBuffers.Descriptors;
using Google.ProtocolBuffers.TestProtos;
using Xunit;

namespace Google.ProtocolBuffers
{
    /// <summary>
    /// Miscellaneous tests for message operations that apply to both
    /// generated and dynamic messages.
    /// </summary>
    public class MessageTest
    {
        // =================================================================
        // Message-merging tests.

        private static readonly TestAllTypes MergeSource = new TestAllTypes.Builder
                                                               {
                                                                   OptionalInt32 = 1,
                                                                   OptionalString = "foo",
                                                                   OptionalForeignMessage =
                                                                       ForeignMessage.DefaultInstance,
                                                               }.AddRepeatedString("bar").Build();

        private static readonly TestAllTypes MergeDest = new TestAllTypes.Builder
                                                             {
                                                                 OptionalInt64 = 2,
                                                                 OptionalString = "baz",
                                                                 OptionalForeignMessage =
                                                                     new ForeignMessage.Builder {C = 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()
        {
            TestAllTypes result = TestAllTypes.CreateBuilder(MergeDest).MergeFrom(MergeSource).Build();

            Assert.Equal(MergeResultText, result.ToString());
        }

        /// <summary>
        /// Test merging a DynamicMessage into a GeneratedMessage. 
        /// As long as they have the same descriptor, this should work, but it is an
        /// entirely different code path.
        /// </summary>
        [Fact]
        public void MergeFromDynamic()
        {
            TestAllTypes result = (TestAllTypes) TestAllTypes.CreateBuilder(MergeDest)
                                                     .MergeFrom(DynamicMessage.CreateBuilder(MergeSource).Build())
                                                     .Build();

            Assert.Equal(MergeResultText, result.ToString());
        }

        /// <summary>
        /// Test merging two DynamicMessages.
        /// </summary>
        [Fact]
        public void DynamicMergeFrom()
        {
            DynamicMessage result = (DynamicMessage) DynamicMessage.CreateBuilder(MergeDest)
                                                         .MergeFrom(
                                                             (DynamicMessage)
                                                             DynamicMessage.CreateBuilder(MergeSource).Build())
                                                         .Build();

            Assert.Equal(MergeResultText, result.ToString());
        }

        // =================================================================
        // Required-field-related tests.

        private static readonly TestRequired TestRequiredUninitialized = TestRequired.DefaultInstance;

        private static readonly TestRequired TestRequiredInitialized = new TestRequired.Builder
                                                                           {
                                                                               A = 1,
                                                                               B = 2,
                                                                               C = 3
                                                                           }.Build();

        [Fact]
        public void Initialization()
        {
            TestRequired.Builder builder = TestRequired.CreateBuilder();

            Assert.False(builder.IsInitialized);
            builder.A = 1;
            Assert.False(builder.IsInitialized);
            builder.B = 1;
            Assert.False(builder.IsInitialized);
            builder.C = 1;
            Assert.True(builder.IsInitialized);
        }

        [Fact]
        public void UninitializedBuilderToString()
        {
            TestRequired.Builder builder = TestRequired.CreateBuilder().SetA(1);
            Assert.Equal("a: 1\n", builder.ToString());
        }

        [Fact]
        public void RequiredForeign()
        {
            TestRequiredForeign.Builder builder = TestRequiredForeign.CreateBuilder();

            Assert.True(builder.IsInitialized);

            builder.SetOptionalMessage(TestRequiredUninitialized);
            Assert.False(builder.IsInitialized);

            builder.SetOptionalMessage(TestRequiredInitialized);
            Assert.True(builder.IsInitialized);

            builder.AddRepeatedMessage(TestRequiredUninitialized);
            Assert.False(builder.IsInitialized);

            builder.SetRepeatedMessage(0, TestRequiredInitialized);
            Assert.True(builder.IsInitialized);
        }

        [Fact]
        public void RequiredExtension()
        {
            TestAllExtensions.Builder builder = TestAllExtensions.CreateBuilder();

            Assert.True(builder.IsInitialized);

            builder.SetExtension(TestRequired.Single, TestRequiredUninitialized);
            Assert.False(builder.IsInitialized);

            builder.SetExtension(TestRequired.Single, TestRequiredInitialized);
            Assert.True(builder.IsInitialized);

            builder.AddExtension(TestRequired.Multi, TestRequiredUninitialized);
            Assert.False(builder.IsInitialized);

            builder.SetExtension(TestRequired.Multi, 0, TestRequiredInitialized);
            Assert.True(builder.IsInitialized);
        }

        [Fact]
        public void RequiredDynamic()
        {
            MessageDescriptor descriptor = TestRequired.Descriptor;
            DynamicMessage.Builder builder = DynamicMessage.CreateBuilder(descriptor);

            Assert.False(builder.IsInitialized);
            builder[descriptor.FindDescriptor<FieldDescriptor>("a")] = 1;
            Assert.False(builder.IsInitialized);
            builder[descriptor.FindDescriptor<FieldDescriptor>("b")] = 1;
            Assert.False(builder.IsInitialized);
            builder[descriptor.FindDescriptor<FieldDescriptor>("c")] = 1;
            Assert.True(builder.IsInitialized);
        }

        [Fact]
        public void RequiredDynamicForeign()
        {
            MessageDescriptor descriptor = TestRequiredForeign.Descriptor;
            DynamicMessage.Builder builder = DynamicMessage.CreateBuilder(descriptor);

            Assert.True(builder.IsInitialized);

            builder[descriptor.FindDescriptor<FieldDescriptor>("optional_message")] = TestRequiredUninitialized;
            Assert.False(builder.IsInitialized);

            builder[descriptor.FindDescriptor<FieldDescriptor>("optional_message")] = TestRequiredInitialized;
            Assert.True(builder.IsInitialized);

            builder.AddRepeatedField(descriptor.FindDescriptor<FieldDescriptor>("repeated_message"),
                                     TestRequiredUninitialized);
            Assert.False(builder.IsInitialized);

            builder.SetRepeatedField(descriptor.FindDescriptor<FieldDescriptor>("repeated_message"), 0,
                                     TestRequiredInitialized);
            Assert.True(builder.IsInitialized);
        }

        [Fact]
        public void UninitializedException()
        {
            var e = Assert.Throws<UninitializedMessageException>(() => TestRequired.CreateBuilder().Build());
            Assert.Equal("Message missing required fields: a, b, c", e.Message);
        }

        [Fact]
        public void BuildPartial()
        {
            // We're mostly testing that no exception is thrown.
            TestRequired message = TestRequired.CreateBuilder().BuildPartial();
            Assert.False(message.IsInitialized);
        }

        [Fact]
        public void NestedUninitializedException()
        {
            var e = Assert.Throws<UninitializedMessageException>(() => TestRequiredForeign.CreateBuilder()
                    .SetOptionalMessage(TestRequiredUninitialized)
                    .AddRepeatedMessage(TestRequiredUninitialized)
                    .AddRepeatedMessage(TestRequiredUninitialized)
                    .Build());
            Assert.Equal(
                "Message missing required fields: " +
                "optional_message.a, " +
                "optional_message.b, " +
                "optional_message.c, " +
                "repeated_message[0].a, " +
                "repeated_message[0].b, " +
                "repeated_message[0].c, " +
                "repeated_message[1].a, " +
                "repeated_message[1].b, " +
                "repeated_message[1].c",
                e.Message);
        }

        [Fact]
        public void BuildNestedPartial()
        {
            // We're mostly testing that no exception is thrown.
            TestRequiredForeign message =
                TestRequiredForeign.CreateBuilder()
                    .SetOptionalMessage(TestRequiredUninitialized)
                    .AddRepeatedMessage(TestRequiredUninitialized)
                    .AddRepeatedMessage(TestRequiredUninitialized)
                    .BuildPartial();
            Assert.False(message.IsInitialized);
        }

        [Fact]
        public void ParseUninitialized()
        {
            var e = Assert.Throws<InvalidProtocolBufferException>(() => TestRequired.ParseFrom(ByteString.Empty));
            Assert.Equal("Message missing required fields: a, b, c", e.Message);
        }

        [Fact]
        public void ParseNestedUnititialized()
        {
            ByteString data =
                TestRequiredForeign.CreateBuilder()
                    .SetOptionalMessage(TestRequiredUninitialized)
                    .AddRepeatedMessage(TestRequiredUninitialized)
                    .AddRepeatedMessage(TestRequiredUninitialized)
                    .BuildPartial().ToByteString();

            var e = Assert.Throws<InvalidProtocolBufferException>(() => TestRequiredForeign.ParseFrom(data));
            Assert.Equal(
                "Message missing required fields: " +
                "optional_message.a, " +
                "optional_message.b, " +
                "optional_message.c, " +
                "repeated_message[0].a, " +
                "repeated_message[0].b, " +
                "repeated_message[0].c, " +
                "repeated_message[1].a, " +
                "repeated_message[1].b, " +
                "repeated_message[1].c",
                e.Message);
        }

        [Fact]
        public void DynamicUninitializedException()
        {
            var e = Assert.Throws<UninitializedMessageException>(() => DynamicMessage.CreateBuilder(TestRequired.Descriptor).Build());
            Assert.Equal("Message missing required fields: a, b, c", e.Message);
        }

        [Fact]
        public void DynamicBuildPartial()
        {
            // We're mostly testing that no exception is thrown.
            DynamicMessage message = DynamicMessage.CreateBuilder(TestRequired.Descriptor).BuildPartial();
            Assert.False(message.Initialized);
        }

        [Fact]
        public void DynamicParseUnititialized()
        {
            MessageDescriptor descriptor = TestRequired.Descriptor;
            var e = Assert.Throws<InvalidProtocolBufferException>(() => DynamicMessage.ParseFrom(descriptor, ByteString.Empty));
            Assert.Equal("Message missing required fields: a, b, c", e.Message);
        }

        [Fact]
        public void PackedTypesWrittenDirectlyToStream()
        {
            TestPackedTypes message = new TestPackedTypes.Builder {PackedInt32List = {0, 1, 2}}.Build();
            MemoryStream stream = new MemoryStream();
            message.WriteTo(stream);
            stream.Position = 0;
            TestPackedTypes readMessage = TestPackedTypes.ParseFrom(stream);
            Assert.Equal(message, readMessage);
        }
    }
}