#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 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 LiteTest
    {
        [Fact]
        public void TestLite()
        {
            // Since lite messages are a subset of regular messages, we can mostly
            // assume that the functionality of lite messages is already thoroughly
            // tested by the regular tests.  All this test really verifies is that
            // a proto with optimize_for = LITE_RUNTIME compiles correctly when
            // linked only against the lite library.  That is all tested at compile
            // time, leaving not much to do in this method.  Let's just do some random
            // stuff to make sure the lite message is actually here and usable.

            TestAllTypesLite message =
                TestAllTypesLite.CreateBuilder()
                    .SetOptionalInt32(123)
                    .AddRepeatedString("hello")
                    .SetOptionalNestedMessage(
                        TestAllTypesLite.Types.NestedMessage.CreateBuilder().SetBb(7))
                    .Build();

            ByteString data = message.ToByteString();

            TestAllTypesLite message2 = TestAllTypesLite.ParseFrom(data);

            Assert.Equal(123, message2.OptionalInt32);
            Assert.Equal(1, message2.RepeatedStringCount);
            Assert.Equal("hello", message2.RepeatedStringList[0]);
            Assert.Equal(7, message2.OptionalNestedMessage.Bb);
        }

        [Fact]
        public void TestLiteExtensions()
        {
            // TODO(kenton):  Unlike other features of the lite library, extensions are
            //   implemented completely differently from the regular library.  We
            //   should probably test them more thoroughly.

            TestAllExtensionsLite message =
                TestAllExtensionsLite.CreateBuilder()
                    .SetExtension(UnittestLite.OptionalInt32ExtensionLite, 123)
                    .AddExtension(UnittestLite.RepeatedStringExtensionLite, "hello")
                    .SetExtension(UnittestLite.OptionalNestedEnumExtensionLite,
                                  TestAllTypesLite.Types.NestedEnum.BAZ)
                    .SetExtension(UnittestLite.OptionalNestedMessageExtensionLite,
                                  TestAllTypesLite.Types.NestedMessage.CreateBuilder().SetBb(7).Build())
                    .Build();

            // Test copying a message, since coping extensions actually does use a
            // different code path between lite and regular libraries, and as of this
            // writing, parsing hasn't been implemented yet.
            TestAllExtensionsLite message2 = message.ToBuilder().Build();

            Assert.Equal(123, (int) message2.GetExtension(
                UnittestLite.OptionalInt32ExtensionLite));
            Assert.Equal(1, message2.GetExtensionCount(
                UnittestLite.RepeatedStringExtensionLite));
            Assert.Equal(1, message2.GetExtension(
                UnittestLite.RepeatedStringExtensionLite).Count);
            Assert.Equal("hello", message2.GetExtension(
                UnittestLite.RepeatedStringExtensionLite, 0));
            Assert.Equal(TestAllTypesLite.Types.NestedEnum.BAZ, message2.GetExtension(
                UnittestLite.OptionalNestedEnumExtensionLite));
            Assert.Equal(7, message2.GetExtension(
                UnittestLite.OptionalNestedMessageExtensionLite).Bb);
        }
    }
}