// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc.  All rights reserved.
// 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.

package com.google.protobuf;

import protobuf_unittest.UnittestProto.TestAllTypes;
import protobuf_unittest.UnittestProto.TestAllExtensions;
import protobuf_unittest.UnittestProto.TestRequired;
import protobuf_unittest.UnittestProto.TestRequiredForeign;
import protobuf_unittest.UnittestProto.ForeignMessage;

import junit.framework.TestCase;

import java.util.List;

/**
 * Misc. unit tests for message operations that apply to both generated
 * and dynamic messages.
 *
 * @author kenton@google.com Kenton Varda
 */
public class MessageTest extends TestCase {
  // =================================================================
  // Message-merging tests.

  static final TestAllTypes MERGE_SOURCE =
    TestAllTypes.newBuilder()
      .setOptionalInt32(1)
      .setOptionalString("foo")
      .setOptionalForeignMessage(ForeignMessage.getDefaultInstance())
      .addRepeatedString("bar")
      .build();

  static final TestAllTypes MERGE_DEST =
    TestAllTypes.newBuilder()
      .setOptionalInt64(2)
      .setOptionalString("baz")
      .setOptionalForeignMessage(ForeignMessage.newBuilder().setC(3).build())
      .addRepeatedString("qux")
      .build();

  static final String MERGE_RESULT_TEXT =
      "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";

  public void testMergeFrom() throws Exception {
    TestAllTypes result =
      TestAllTypes.newBuilder(MERGE_DEST)
        .mergeFrom(MERGE_SOURCE).build();

    assertEquals(MERGE_RESULT_TEXT, result.toString());
  }

  /**
   * 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.
   */
  public void testMergeFromDynamic() throws Exception {
    TestAllTypes result =
      TestAllTypes.newBuilder(MERGE_DEST)
        .mergeFrom(DynamicMessage.newBuilder(MERGE_SOURCE).build())
        .build();

    assertEquals(MERGE_RESULT_TEXT, result.toString());
  }

  /** Test merging two DynamicMessages. */
  public void testDynamicMergeFrom() throws Exception {
    DynamicMessage result =
      DynamicMessage.newBuilder(MERGE_DEST)
        .mergeFrom(DynamicMessage.newBuilder(MERGE_SOURCE).build())
        .build();

    assertEquals(MERGE_RESULT_TEXT, result.toString());
  }

  // =================================================================
  // Required-field-related tests.

  private static final TestRequired TEST_REQUIRED_UNINITIALIZED =
    TestRequired.getDefaultInstance();
  private static final TestRequired TEST_REQUIRED_INITIALIZED =
    TestRequired.newBuilder().setA(1).setB(2).setC(3).build();

  public void testRequired() throws Exception {
    TestRequired.Builder builder = TestRequired.newBuilder();

    assertFalse(builder.isInitialized());
    builder.setA(1);
    assertFalse(builder.isInitialized());
    builder.setB(1);
    assertFalse(builder.isInitialized());
    builder.setC(1);
    assertTrue(builder.isInitialized());
  }

  public void testRequiredForeign() throws Exception {
    TestRequiredForeign.Builder builder = TestRequiredForeign.newBuilder();

    assertTrue(builder.isInitialized());

    builder.setOptionalMessage(TEST_REQUIRED_UNINITIALIZED);
    assertFalse(builder.isInitialized());

    builder.setOptionalMessage(TEST_REQUIRED_INITIALIZED);
    assertTrue(builder.isInitialized());

    builder.addRepeatedMessage(TEST_REQUIRED_UNINITIALIZED);
    assertFalse(builder.isInitialized());

    builder.setRepeatedMessage(0, TEST_REQUIRED_INITIALIZED);
    assertTrue(builder.isInitialized());
  }

  public void testRequiredExtension() throws Exception {
    TestAllExtensions.Builder builder = TestAllExtensions.newBuilder();

    assertTrue(builder.isInitialized());

    builder.setExtension(TestRequired.single, TEST_REQUIRED_UNINITIALIZED);
    assertFalse(builder.isInitialized());

    builder.setExtension(TestRequired.single, TEST_REQUIRED_INITIALIZED);
    assertTrue(builder.isInitialized());

    builder.addExtension(TestRequired.multi, TEST_REQUIRED_UNINITIALIZED);
    assertFalse(builder.isInitialized());

    builder.setExtension(TestRequired.multi, 0, TEST_REQUIRED_INITIALIZED);
    assertTrue(builder.isInitialized());
  }

  public void testRequiredDynamic() throws Exception {
    Descriptors.Descriptor descriptor = TestRequired.getDescriptor();
    DynamicMessage.Builder builder = DynamicMessage.newBuilder(descriptor);

    assertFalse(builder.isInitialized());
    builder.setField(descriptor.findFieldByName("a"), 1);
    assertFalse(builder.isInitialized());
    builder.setField(descriptor.findFieldByName("b"), 1);
    assertFalse(builder.isInitialized());
    builder.setField(descriptor.findFieldByName("c"), 1);
    assertTrue(builder.isInitialized());
  }

  public void testRequiredDynamicForeign() throws Exception {
    Descriptors.Descriptor descriptor = TestRequiredForeign.getDescriptor();
    DynamicMessage.Builder builder = DynamicMessage.newBuilder(descriptor);

    assertTrue(builder.isInitialized());

    builder.setField(descriptor.findFieldByName("optional_message"),
                     TEST_REQUIRED_UNINITIALIZED);
    assertFalse(builder.isInitialized());

    builder.setField(descriptor.findFieldByName("optional_message"),
                     TEST_REQUIRED_INITIALIZED);
    assertTrue(builder.isInitialized());

    builder.addRepeatedField(descriptor.findFieldByName("repeated_message"),
                             TEST_REQUIRED_UNINITIALIZED);
    assertFalse(builder.isInitialized());

    builder.setRepeatedField(descriptor.findFieldByName("repeated_message"), 0,
                             TEST_REQUIRED_INITIALIZED);
    assertTrue(builder.isInitialized());
  }

  public void testUninitializedException() throws Exception {
    try {
      TestRequired.newBuilder().build();
      fail("Should have thrown an exception.");
    } catch (UninitializedMessageException e) {
      assertEquals("Message missing required fields: a, b, c", e.getMessage());
    }
  }

  public void testBuildPartial() throws Exception {
    // We're mostly testing that no exception is thrown.
    TestRequired message = TestRequired.newBuilder().buildPartial();
    assertFalse(message.isInitialized());
  }

  public void testNestedUninitializedException() throws Exception {
    try {
      TestRequiredForeign.newBuilder()
        .setOptionalMessage(TEST_REQUIRED_UNINITIALIZED)
        .addRepeatedMessage(TEST_REQUIRED_UNINITIALIZED)
        .addRepeatedMessage(TEST_REQUIRED_UNINITIALIZED)
        .build();
      fail("Should have thrown an exception.");
    } catch (UninitializedMessageException e) {
      assertEquals(
        "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.getMessage());
    }
  }

  public void testBuildNestedPartial() throws Exception {
    // We're mostly testing that no exception is thrown.
    TestRequiredForeign message =
      TestRequiredForeign.newBuilder()
        .setOptionalMessage(TEST_REQUIRED_UNINITIALIZED)
        .addRepeatedMessage(TEST_REQUIRED_UNINITIALIZED)
        .addRepeatedMessage(TEST_REQUIRED_UNINITIALIZED)
        .buildPartial();
    assertFalse(message.isInitialized());
  }

  public void testParseUnititialized() throws Exception {
    try {
      TestRequired.parseFrom(ByteString.EMPTY);
      fail("Should have thrown an exception.");
    } catch (InvalidProtocolBufferException e) {
      assertEquals("Message missing required fields: a, b, c", e.getMessage());
    }
  }

  public void testParseNestedUnititialized() throws Exception {
    ByteString data =
      TestRequiredForeign.newBuilder()
        .setOptionalMessage(TEST_REQUIRED_UNINITIALIZED)
        .addRepeatedMessage(TEST_REQUIRED_UNINITIALIZED)
        .addRepeatedMessage(TEST_REQUIRED_UNINITIALIZED)
        .buildPartial().toByteString();

    try {
      TestRequiredForeign.parseFrom(data);
      fail("Should have thrown an exception.");
    } catch (InvalidProtocolBufferException e) {
      assertEquals(
        "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.getMessage());
    }
  }

  public void testDynamicUninitializedException() throws Exception {
    try {
      DynamicMessage.newBuilder(TestRequired.getDescriptor()).build();
      fail("Should have thrown an exception.");
    } catch (UninitializedMessageException e) {
      assertEquals("Message missing required fields: a, b, c", e.getMessage());
    }
  }

  public void testDynamicBuildPartial() throws Exception {
    // We're mostly testing that no exception is thrown.
    DynamicMessage message =
      DynamicMessage.newBuilder(TestRequired.getDescriptor())
        .buildPartial();
    assertFalse(message.isInitialized());
  }

  public void testDynamicParseUnititialized() throws Exception {
    try {
      Descriptors.Descriptor descriptor = TestRequired.getDescriptor();
      DynamicMessage.parseFrom(descriptor, ByteString.EMPTY);
      fail("Should have thrown an exception.");
    } catch (InvalidProtocolBufferException e) {
      assertEquals("Message missing required fields: a, b, c", e.getMessage());
    }
  }
  
  /** Test reading unset repeated message from DynamicMessage. */
  public void testDynamicRepeatedMessageNull() throws Exception {
    Descriptors.Descriptor descriptor = TestRequired.getDescriptor();
    DynamicMessage result =
      DynamicMessage.newBuilder(TestAllTypes.getDescriptor())
        .mergeFrom(DynamicMessage.newBuilder(MERGE_SOURCE).build())
        .build();

    assertTrue(result.getField(result.getDescriptorForType()
        .findFieldByName("repeated_foreign_message")) instanceof List<?>);
    assertEquals(result.getRepeatedFieldCount(result.getDescriptorForType()
        .findFieldByName("repeated_foreign_message")), 0);
  }
  
  /** Test reading repeated message from DynamicMessage. */
  public void testDynamicRepeatedMessageNotNull() throws Exception {

    TestAllTypes REPEATED_NESTED =
      TestAllTypes.newBuilder()
        .setOptionalInt32(1)
        .setOptionalString("foo")
        .setOptionalForeignMessage(ForeignMessage.getDefaultInstance())
        .addRepeatedString("bar")
        .addRepeatedForeignMessage(ForeignMessage.getDefaultInstance())
        .addRepeatedForeignMessage(ForeignMessage.getDefaultInstance())
        .build();
    Descriptors.Descriptor descriptor = TestRequired.getDescriptor();
    DynamicMessage result =
      DynamicMessage.newBuilder(TestAllTypes.getDescriptor())
        .mergeFrom(DynamicMessage.newBuilder(REPEATED_NESTED).build())
        .build();

    assertTrue(result.getField(result.getDescriptorForType()
        .findFieldByName("repeated_foreign_message")) instanceof List<?>);
    assertEquals(result.getRepeatedFieldCount(result.getDescriptorForType()
        .findFieldByName("repeated_foreign_message")), 2);
  }
}
