// 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 com.google.protobuf.Descriptors.FieldDescriptor;
import protobuf_unittest.UnittestOptimizeFor.TestOptimizedForSize;
import protobuf_unittest.UnittestProto;
import protobuf_unittest.UnittestProto.ForeignMessage;
import protobuf_unittest.UnittestProto.TestAllExtensions;
import protobuf_unittest.UnittestProto.TestAllTypes;
import protobuf_unittest.UnittestProto.TestPackedTypes;
import protobuf_unittest.UnittestProto.TestRequired;
import protobuf_unittest.UnittestProto.TestRequiredForeign;
import protobuf_unittest.UnittestProto.TestUnpackedTypes;

import junit.framework.TestCase;

import java.util.Map;

/**
 * Unit test for {@link AbstractMessage}.
 *
 * @author kenton@google.com Kenton Varda
 */
public class AbstractMessageTest extends TestCase {
  /**
   * 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.
   */
  private static class AbstractMessageWrapper extends AbstractMessage {
    private final Message wrappedMessage;

    public AbstractMessageWrapper(Message wrappedMessage) {
      this.wrappedMessage = wrappedMessage;
    }

    public Descriptors.Descriptor getDescriptorForType() {
      return wrappedMessage.getDescriptorForType();
    }
    public AbstractMessageWrapper getDefaultInstanceForType() {
      return new AbstractMessageWrapper(
        wrappedMessage.getDefaultInstanceForType());
    }
    public Map<Descriptors.FieldDescriptor, Object> getAllFields() {
      return wrappedMessage.getAllFields();
    }
    public boolean hasField(Descriptors.FieldDescriptor field) {
      return wrappedMessage.hasField(field);
    }
    public Object getField(Descriptors.FieldDescriptor field) {
      return wrappedMessage.getField(field);
    }
    public int getRepeatedFieldCount(Descriptors.FieldDescriptor field) {
      return wrappedMessage.getRepeatedFieldCount(field);
    }
    public Object getRepeatedField(
        Descriptors.FieldDescriptor field, int index) {
      return wrappedMessage.getRepeatedField(field, index);
    }
    public UnknownFieldSet getUnknownFields() {
      return wrappedMessage.getUnknownFields();
    }
    public Builder newBuilderForType() {
      return new Builder(wrappedMessage.newBuilderForType());
    }
    public Builder toBuilder() {
      return new Builder(wrappedMessage.toBuilder());
    }

    static class Builder extends AbstractMessage.Builder<Builder> {
      private final Message.Builder wrappedBuilder;

      public Builder(Message.Builder wrappedBuilder) {
        this.wrappedBuilder = wrappedBuilder;
      }

      public AbstractMessageWrapper build() {
        return new AbstractMessageWrapper(wrappedBuilder.build());
      }
      public AbstractMessageWrapper buildPartial() {
        return new AbstractMessageWrapper(wrappedBuilder.buildPartial());
      }
      public Builder clone() {
        return new Builder(wrappedBuilder.clone());
      }
      public boolean isInitialized() {
        return clone().buildPartial().isInitialized();
      }
      public Descriptors.Descriptor getDescriptorForType() {
        return wrappedBuilder.getDescriptorForType();
      }
      public AbstractMessageWrapper getDefaultInstanceForType() {
        return new AbstractMessageWrapper(
          wrappedBuilder.getDefaultInstanceForType());
      }
      public Map<Descriptors.FieldDescriptor, Object> getAllFields() {
        return wrappedBuilder.getAllFields();
      }
      public Builder newBuilderForField(Descriptors.FieldDescriptor field) {
        return new Builder(wrappedBuilder.newBuilderForField(field));
      }
      public boolean hasField(Descriptors.FieldDescriptor field) {
        return wrappedBuilder.hasField(field);
      }
      public Object getField(Descriptors.FieldDescriptor field) {
        return wrappedBuilder.getField(field);
      }
      public Builder setField(Descriptors.FieldDescriptor field, Object value) {
        wrappedBuilder.setField(field, value);
        return this;
      }
      public Builder clearField(Descriptors.FieldDescriptor field) {
        wrappedBuilder.clearField(field);
        return this;
      }
      public int getRepeatedFieldCount(Descriptors.FieldDescriptor field) {
        return wrappedBuilder.getRepeatedFieldCount(field);
      }
      public Object getRepeatedField(
          Descriptors.FieldDescriptor field, int index) {
        return wrappedBuilder.getRepeatedField(field, index);
      }
      public Builder setRepeatedField(Descriptors.FieldDescriptor field,
                                      int index, Object value) {
        wrappedBuilder.setRepeatedField(field, index, value);
        return this;
      }
      public Builder addRepeatedField(
          Descriptors.FieldDescriptor field, Object value) {
        wrappedBuilder.addRepeatedField(field, value);
        return this;
      }
      public UnknownFieldSet getUnknownFields() {
        return wrappedBuilder.getUnknownFields();
      }
      public Builder setUnknownFields(UnknownFieldSet unknownFields) {
        wrappedBuilder.setUnknownFields(unknownFields);
        return this;
      }
      @Override
      public Message.Builder getFieldBuilder(FieldDescriptor field) {
        return wrappedBuilder.getFieldBuilder(field);
      }
    }
    public Parser<? extends Message> getParserForType() {
      return wrappedMessage.getParserForType();
    }
  }

  // =================================================================

  TestUtil.ReflectionTester reflectionTester =
    new TestUtil.ReflectionTester(TestAllTypes.getDescriptor(), null);

  TestUtil.ReflectionTester extensionsReflectionTester =
    new TestUtil.ReflectionTester(TestAllExtensions.getDescriptor(),
                                  TestUtil.getExtensionRegistry());

  public void testClear() throws Exception {
    AbstractMessageWrapper message =
      new AbstractMessageWrapper.Builder(
          TestAllTypes.newBuilder(TestUtil.getAllSet()))
        .clear().build();
    TestUtil.assertClear((TestAllTypes) message.wrappedMessage);
  }

  public void testCopy() throws Exception {
    AbstractMessageWrapper message =
      new AbstractMessageWrapper.Builder(TestAllTypes.newBuilder())
        .mergeFrom(TestUtil.getAllSet()).build();
    TestUtil.assertAllFieldsSet((TestAllTypes) message.wrappedMessage);
  }

  public void testSerializedSize() throws Exception {
    TestAllTypes message = TestUtil.getAllSet();
    Message abstractMessage = new AbstractMessageWrapper(TestUtil.getAllSet());

    assertEquals(message.getSerializedSize(),
                 abstractMessage.getSerializedSize());
  }

  public void testSerialization() throws Exception {
    Message abstractMessage = new AbstractMessageWrapper(TestUtil.getAllSet());

    TestUtil.assertAllFieldsSet(
      TestAllTypes.parseFrom(abstractMessage.toByteString()));

    assertEquals(TestUtil.getAllSet().toByteString(),
                 abstractMessage.toByteString());
  }

  public void testParsing() throws Exception {
    AbstractMessageWrapper.Builder builder =
      new AbstractMessageWrapper.Builder(TestAllTypes.newBuilder());
    AbstractMessageWrapper message =
      builder.mergeFrom(TestUtil.getAllSet().toByteString()).build();
    TestUtil.assertAllFieldsSet((TestAllTypes) message.wrappedMessage);
  }

  public void testParsingUninitialized() throws Exception {
    TestRequiredForeign.Builder builder = TestRequiredForeign.newBuilder();
    builder.getOptionalMessageBuilder().setDummy2(10);
    ByteString bytes = builder.buildPartial().toByteString();
    Message.Builder abstractMessageBuilder =
        new AbstractMessageWrapper.Builder(TestRequiredForeign.newBuilder());
    // mergeFrom() should not throw initialization error.
    abstractMessageBuilder.mergeFrom(bytes).buildPartial();
    try {
      abstractMessageBuilder.mergeFrom(bytes).build();
      fail();
    } catch (UninitializedMessageException ex) {
      // pass
    }

    // test DynamicMessage directly.
    Message.Builder dynamicMessageBuilder = DynamicMessage.newBuilder(
        TestRequiredForeign.getDescriptor());
    // mergeFrom() should not throw initialization error.
    dynamicMessageBuilder.mergeFrom(bytes).buildPartial();
    try {
      dynamicMessageBuilder.mergeFrom(bytes).build();
      fail();
    } catch (UninitializedMessageException ex) {
      // pass
    }
  }

  public void testPackedSerialization() throws Exception {
    Message abstractMessage =
        new AbstractMessageWrapper(TestUtil.getPackedSet());

    TestUtil.assertPackedFieldsSet(
      TestPackedTypes.parseFrom(abstractMessage.toByteString()));

    assertEquals(TestUtil.getPackedSet().toByteString(),
                 abstractMessage.toByteString());
  }

  public void testPackedParsing() throws Exception {
    AbstractMessageWrapper.Builder builder =
      new AbstractMessageWrapper.Builder(TestPackedTypes.newBuilder());
    AbstractMessageWrapper message =
      builder.mergeFrom(TestUtil.getPackedSet().toByteString()).build();
    TestUtil.assertPackedFieldsSet((TestPackedTypes) message.wrappedMessage);
  }

  public void testUnpackedSerialization() throws Exception {
    Message abstractMessage =
      new AbstractMessageWrapper(TestUtil.getUnpackedSet());

    TestUtil.assertUnpackedFieldsSet(
      TestUnpackedTypes.parseFrom(abstractMessage.toByteString()));

    assertEquals(TestUtil.getUnpackedSet().toByteString(),
                 abstractMessage.toByteString());
  }

  public void testParsePackedToUnpacked() throws Exception {
    AbstractMessageWrapper.Builder builder =
      new AbstractMessageWrapper.Builder(TestUnpackedTypes.newBuilder());
    AbstractMessageWrapper message =
      builder.mergeFrom(TestUtil.getPackedSet().toByteString()).build();
    TestUtil.assertUnpackedFieldsSet(
      (TestUnpackedTypes) message.wrappedMessage);
  }

  public void testParseUnpackedToPacked() throws Exception {
    AbstractMessageWrapper.Builder builder =
      new AbstractMessageWrapper.Builder(TestPackedTypes.newBuilder());
    AbstractMessageWrapper message =
      builder.mergeFrom(TestUtil.getUnpackedSet().toByteString()).build();
    TestUtil.assertPackedFieldsSet((TestPackedTypes) message.wrappedMessage);
  }

  public void testUnpackedParsing() throws Exception {
    AbstractMessageWrapper.Builder builder =
      new AbstractMessageWrapper.Builder(TestUnpackedTypes.newBuilder());
    AbstractMessageWrapper message =
      builder.mergeFrom(TestUtil.getUnpackedSet().toByteString()).build();
    TestUtil.assertUnpackedFieldsSet(
      (TestUnpackedTypes) message.wrappedMessage);
  }

  public void testOptimizedForSize() throws Exception {
    // We're mostly only checking that this class was compiled successfully.
    TestOptimizedForSize message =
      TestOptimizedForSize.newBuilder().setI(1).build();
    message = TestOptimizedForSize.parseFrom(message.toByteString());
    assertEquals(2, message.getSerializedSize());
  }

  // -----------------------------------------------------------------
  // Tests for isInitialized().

  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 testIsInitialized() throws Exception {
    TestRequired.Builder builder = TestRequired.newBuilder();
    AbstractMessageWrapper.Builder abstractBuilder =
      new AbstractMessageWrapper.Builder(builder);

    assertFalse(abstractBuilder.isInitialized());
    assertEquals("a, b, c", abstractBuilder.getInitializationErrorString());
    builder.setA(1);
    assertFalse(abstractBuilder.isInitialized());
    assertEquals("b, c", abstractBuilder.getInitializationErrorString());
    builder.setB(1);
    assertFalse(abstractBuilder.isInitialized());
    assertEquals("c", abstractBuilder.getInitializationErrorString());
    builder.setC(1);
    assertTrue(abstractBuilder.isInitialized());
    assertEquals("", abstractBuilder.getInitializationErrorString());
  }

  public void testForeignIsInitialized() throws Exception {
    TestRequiredForeign.Builder builder = TestRequiredForeign.newBuilder();
    AbstractMessageWrapper.Builder abstractBuilder =
      new AbstractMessageWrapper.Builder(builder);

    assertTrue(abstractBuilder.isInitialized());
    assertEquals("", abstractBuilder.getInitializationErrorString());

    builder.setOptionalMessage(TEST_REQUIRED_UNINITIALIZED);
    assertFalse(abstractBuilder.isInitialized());
    assertEquals(
        "optional_message.a, optional_message.b, optional_message.c",
        abstractBuilder.getInitializationErrorString());

    builder.setOptionalMessage(TEST_REQUIRED_INITIALIZED);
    assertTrue(abstractBuilder.isInitialized());
    assertEquals("", abstractBuilder.getInitializationErrorString());

    builder.addRepeatedMessage(TEST_REQUIRED_UNINITIALIZED);
    assertFalse(abstractBuilder.isInitialized());
    assertEquals(
        "repeated_message[0].a, repeated_message[0].b, repeated_message[0].c",
        abstractBuilder.getInitializationErrorString());

    builder.setRepeatedMessage(0, TEST_REQUIRED_INITIALIZED);
    assertTrue(abstractBuilder.isInitialized());
    assertEquals("", abstractBuilder.getInitializationErrorString());
  }

  // -----------------------------------------------------------------
  // Tests for mergeFrom

  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 {
    AbstractMessageWrapper result =
      new AbstractMessageWrapper.Builder(
        TestAllTypes.newBuilder(MERGE_DEST))
      .mergeFrom(MERGE_SOURCE).build();

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

  // -----------------------------------------------------------------
  // Tests for equals and hashCode

  public void testEqualsAndHashCode() throws Exception {
    TestAllTypes a = TestUtil.getAllSet();
    TestAllTypes b = TestAllTypes.newBuilder().build();
    TestAllTypes c = TestAllTypes.newBuilder(b).addRepeatedString("x").build();
    TestAllTypes d = TestAllTypes.newBuilder(c).addRepeatedString("y").build();
    TestAllExtensions e = TestUtil.getAllExtensionsSet();
    TestAllExtensions f = TestAllExtensions.newBuilder(e)
        .addExtension(UnittestProto.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 {@link UnknownFieldSet.Field}.
    UnittestProto.TestEmptyMessage eUnknownFields =
        UnittestProto.TestEmptyMessage.parseFrom(e.toByteArray());
    UnittestProto.TestEmptyMessage fUnknownFields =
        UnittestProto.TestEmptyMessage.parseFrom(f.toByteArray());
    checkNotEqual(eUnknownFields, fUnknownFields);
    checkEqualsIsConsistent(eUnknownFields);
    checkEqualsIsConsistent(fUnknownFields);

    // Subsequent reconstitutions should be identical
    UnittestProto.TestEmptyMessage eUnknownFields2 =
        UnittestProto.TestEmptyMessage.parseFrom(e.toByteArray());
    checkEqualsIsConsistent(eUnknownFields, eUnknownFields2);
  }


  /**
   * Asserts that the given proto has symmetric equals and hashCode methods.
   */
  private void checkEqualsIsConsistent(Message message) {
    // Object should be equal to itself.
    assertEquals(message, message);

    // Object should be equal to a dynamic copy of itself.
    DynamicMessage dynamic = DynamicMessage.newBuilder(message).build();
    checkEqualsIsConsistent(message, dynamic);
  }

  /**
   * Asserts that the given protos are equal and have the same hash code.
   */
  private void checkEqualsIsConsistent(Message message1, Message message2) {
    assertEquals(message1, message2);
    assertEquals(message2, message1);
    assertEquals(message2.hashCode(), message1.hashCode());
  }

  /**
   * Asserts that the given protos are not equal and have different hash codes.
   *
   * @warning 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.
   */
  private void checkNotEqual(Message m1, Message m2) {
    String equalsError = String.format("%s should not be equal to %s", m1, m2);
    assertFalse(equalsError, m1.equals(m2));
    assertFalse(equalsError, m2.equals(m1));

    assertFalse(
        String.format("%s should have a different hash code from %s", m1, m2),
        m1.hashCode() == m2.hashCode());
  }
}
