// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc.  All rights reserved.
// https://developers.google.com/protocol-buffers/
//
// 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 static com.google.protobuf.Internal.UTF_8;

import junit.framework.TestCase;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.EOFException;
import java.io.IOException;
import java.io.InputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.OutputStream;
import java.io.UnsupportedEncodingException;
import java.nio.BufferOverflowException;
import java.nio.ByteBuffer;
import java.util.Arrays;
import java.util.List;
import java.util.NoSuchElementException;

/**
 * Tests for {@link NioByteString}.
 */
public class NioByteStringTest extends TestCase {
  private static final ByteString EMPTY = new NioByteString(ByteBuffer.wrap(new byte[0]));
  private static final String CLASSNAME = NioByteString.class.getSimpleName();
  private static final byte[] BYTES = ByteStringTest.getTestBytes(1234, 11337766L);
  private static final int EXPECTED_HASH = ByteString.wrap(BYTES).hashCode();

  private final ByteBuffer backingBuffer = ByteBuffer.wrap(BYTES.clone());
  private final ByteString testString = new NioByteString(backingBuffer);

  public void testExpectedType() {
    String actualClassName = getActualClassName(testString);
    assertEquals(CLASSNAME + " should match type exactly", CLASSNAME, actualClassName);
  }

  protected String getActualClassName(Object object) {
    String actualClassName = object.getClass().getName();
    actualClassName = actualClassName.substring(actualClassName.lastIndexOf('.') + 1);
    return actualClassName;
  }

  public void testByteAt() {
    boolean stillEqual = true;
    for (int i = 0; stillEqual && i < BYTES.length; ++i) {
      stillEqual = (BYTES[i] == testString.byteAt(i));
    }
    assertTrue(CLASSNAME + " must capture the right bytes", stillEqual);
  }

  public void testByteIterator() {
    boolean stillEqual = true;
    ByteString.ByteIterator iter = testString.iterator();
    for (int i = 0; stillEqual && i < BYTES.length; ++i) {
      stillEqual = (iter.hasNext() && BYTES[i] == iter.nextByte());
    }
    assertTrue(CLASSNAME + " must capture the right bytes", stillEqual);
    assertFalse(CLASSNAME + " must have exhausted the itertor", iter.hasNext());

    try {
      iter.nextByte();
      fail("Should have thrown an exception.");
    } catch (NoSuchElementException e) {
      // This is success
    }
  }

  public void testByteIterable() {
    boolean stillEqual = true;
    int j = 0;
    for (byte quantum : testString) {
      stillEqual = (BYTES[j] == quantum);
      ++j;
    }
    assertTrue(CLASSNAME + " must capture the right bytes as Bytes", stillEqual);
    assertEquals(CLASSNAME + " iterable character count", BYTES.length, j);
  }

  public void testSize() {
    assertEquals(CLASSNAME + " must have the expected size", BYTES.length,
        testString.size());
  }

  public void testGetTreeDepth() {
    assertEquals(CLASSNAME + " must have depth 0", 0, testString.getTreeDepth());
  }

  public void testIsBalanced() {
    assertTrue(CLASSNAME + " is technically balanced", testString.isBalanced());
  }

  public void testCopyTo_ByteArrayOffsetLength() {
    int destinationOffset = 50;
    int length = 100;
    byte[] destination = new byte[destinationOffset + length];
    int sourceOffset = 213;
    testString.copyTo(destination, sourceOffset, destinationOffset, length);
    boolean stillEqual = true;
    for (int i = 0; stillEqual && i < length; ++i) {
      stillEqual = BYTES[i + sourceOffset] == destination[i + destinationOffset];
    }
    assertTrue(CLASSNAME + ".copyTo(4 arg) must give the expected bytes", stillEqual);
  }

  public void testCopyTo_ByteArrayOffsetLengthErrors() {
    int destinationOffset = 50;
    int length = 100;
    byte[] destination = new byte[destinationOffset + length];

    try {
      // Copy one too many bytes
      testString.copyTo(destination, testString.size() + 1 - length,
          destinationOffset, length);
      fail("Should have thrown an exception when copying too many bytes of a "
          + CLASSNAME);
    } catch (IndexOutOfBoundsException expected) {
      // This is success
    }

    try {
      // Copy with illegal negative sourceOffset
      testString.copyTo(destination, -1, destinationOffset, length);
      fail("Should have thrown an exception when given a negative sourceOffset in "
          + CLASSNAME);
    } catch (IndexOutOfBoundsException expected) {
      // This is success
    }

    try {
      // Copy with illegal negative destinationOffset
      testString.copyTo(destination, 0, -1, length);
      fail("Should have thrown an exception when given a negative destinationOffset in "
          + CLASSNAME);
    } catch (IndexOutOfBoundsException expected) {
      // This is success
    }

    try {
      // Copy with illegal negative size
      testString.copyTo(destination, 0, 0, -1);
      fail("Should have thrown an exception when given a negative size in "
          + CLASSNAME);
    } catch (IndexOutOfBoundsException expected) {
      // This is success
    }

    try {
      // Copy with illegal too-large sourceOffset
      testString.copyTo(destination, 2 * testString.size(), 0, length);
      fail("Should have thrown an exception when the destinationOffset is too large in "
          + CLASSNAME);
    } catch (IndexOutOfBoundsException expected) {
      // This is success
    }

    try {
      // Copy with illegal too-large destinationOffset
      testString.copyTo(destination, 0, 2 * destination.length, length);
      fail("Should have thrown an exception when the destinationOffset is too large in "
          + CLASSNAME);
    } catch (IndexOutOfBoundsException expected) {
      // This is success
    }
  }

  public void testCopyTo_ByteBuffer() {
    // Same length.
    ByteBuffer myBuffer = ByteBuffer.allocate(BYTES.length);
    testString.copyTo(myBuffer);
    myBuffer.flip();
    assertEquals(CLASSNAME + ".copyTo(ByteBuffer) must give back the same bytes",
        backingBuffer, myBuffer);

    // Target buffer bigger than required.
    myBuffer = ByteBuffer.allocate(testString.size() + 1);
    testString.copyTo(myBuffer);
    myBuffer.flip();
    assertEquals(backingBuffer, myBuffer);

    // Target buffer has no space.
    myBuffer = ByteBuffer.allocate(0);
    try {
      testString.copyTo(myBuffer);
      fail("Should have thrown an exception when target ByteBuffer has insufficient capacity");
    } catch (BufferOverflowException e) {
      // Expected.
    }

    // Target buffer too small.
    myBuffer = ByteBuffer.allocate(1);
    try {
      testString.copyTo(myBuffer);
      fail("Should have thrown an exception when target ByteBuffer has insufficient capacity");
    } catch (BufferOverflowException e) {
      // Expected.
    }
  }

  public void testMarkSupported() {
    InputStream stream = testString.newInput();
    assertTrue(CLASSNAME + ".newInput() must support marking", stream.markSupported());
  }

  public void testMarkAndReset() throws IOException {
    int fraction = testString.size() / 3;

    InputStream stream = testString.newInput();
    stream.mark(testString.size()); // First, mark() the end.

    skipFully(stream, fraction); // Skip a large fraction, but not all.
    assertEquals(
        CLASSNAME + ": after skipping to the 'middle', half the bytes are available",
        (testString.size() - fraction), stream.available());
    stream.reset();
    assertEquals(
        CLASSNAME + ": after resetting, all bytes are available",
        testString.size(), stream.available());

    skipFully(stream, testString.size()); // Skip to the end.
    assertEquals(
        CLASSNAME + ": after skipping to the end, no more bytes are available",
        0, stream.available());
  }

  /**
   * Discards {@code n} bytes of data from the input stream. This method
   * will block until the full amount has been skipped. Does not close the
   * stream.
   * <p>Copied from com.google.common.io.ByteStreams to avoid adding dependency.
   *
   * @param in the input stream to read from
   * @param n the number of bytes to skip
   * @throws EOFException if this stream reaches the end before skipping all
   *     the bytes
   * @throws IOException if an I/O error occurs, or the stream does not
   *     support skipping
   */
  static void skipFully(InputStream in, long n) throws IOException {
    long toSkip = n;
    while (n > 0) {
      long amt = in.skip(n);
      if (amt == 0) {
        // Force a blocking read to avoid infinite loop
        if (in.read() == -1) {
          long skipped = toSkip - n;
          throw new EOFException("reached end of stream after skipping "
              + skipped + " bytes; " + toSkip + " bytes expected");
        }
        n--;
      } else {
        n -= amt;
      }
    }
  }

  public void testAsReadOnlyByteBuffer() {
    ByteBuffer byteBuffer = testString.asReadOnlyByteBuffer();
    byte[] roundTripBytes = new byte[BYTES.length];
    assertTrue(byteBuffer.remaining() == BYTES.length);
    assertTrue(byteBuffer.isReadOnly());
    byteBuffer.get(roundTripBytes);
    assertTrue(CLASSNAME + ".asReadOnlyByteBuffer() must give back the same bytes",
        Arrays.equals(BYTES, roundTripBytes));
  }

  public void testAsReadOnlyByteBufferList() {
    List<ByteBuffer> byteBuffers = testString.asReadOnlyByteBufferList();
    int bytesSeen = 0;
    byte[] roundTripBytes = new byte[BYTES.length];
    for (ByteBuffer byteBuffer : byteBuffers) {
      int thisLength = byteBuffer.remaining();
      assertTrue(byteBuffer.isReadOnly());
      assertTrue(bytesSeen + thisLength <= BYTES.length);
      byteBuffer.get(roundTripBytes, bytesSeen, thisLength);
      bytesSeen += thisLength;
    }
    assertTrue(bytesSeen == BYTES.length);
    assertTrue(CLASSNAME + ".asReadOnlyByteBufferTest() must give back the same bytes",
        Arrays.equals(BYTES, roundTripBytes));
  }

  public void testToByteArray() {
    byte[] roundTripBytes = testString.toByteArray();
    assertTrue(CLASSNAME + ".toByteArray() must give back the same bytes",
        Arrays.equals(BYTES, roundTripBytes));
  }

  public void testWriteTo() throws IOException {
    ByteArrayOutputStream bos = new ByteArrayOutputStream();
    testString.writeTo(bos);
    byte[] roundTripBytes = bos.toByteArray();
    assertTrue(CLASSNAME + ".writeTo() must give back the same bytes",
        Arrays.equals(BYTES, roundTripBytes));
  }

  public void testWriteToShouldNotExposeInternalBufferToOutputStream() throws IOException {
    OutputStream os = new OutputStream() {
      @Override
      public void write(byte[] b, int off, int len) {
        Arrays.fill(b, off, off + len, (byte) 0);
      }

      @Override
      public void write(int b) {
        throw new UnsupportedOperationException();
      }
    };

    byte[] original = Arrays.copyOf(BYTES, BYTES.length);
    testString.writeTo(os);
    assertTrue(CLASSNAME + ".writeTo() must NOT grant access to underlying buffer",
        Arrays.equals(original, BYTES));
  }

  public void testWriteToInternalShouldExposeInternalBufferToOutputStream() throws IOException {
    OutputStream os = new OutputStream() {
      @Override
      public void write(byte[] b, int off, int len) {
        Arrays.fill(b, off, off + len, (byte) 0);
      }

      @Override
      public void write(int b) {
        throw new UnsupportedOperationException();
      }
    };

    testString.writeToInternal(os, 0, testString.size());
    byte[] allZeros = new byte[testString.size()];
    assertTrue(CLASSNAME + ".writeToInternal() must grant access to underlying buffer",
        Arrays.equals(allZeros, backingBuffer.array()));
  }

  public void testWriteToShouldExposeInternalBufferToByteOutput() throws IOException {
    ByteOutput out = new ByteOutput() {
      @Override
      public void write(byte value) throws IOException {
        throw new UnsupportedOperationException();
      }

      @Override
      public void write(byte[] value, int offset, int length) throws IOException {
        throw new UnsupportedOperationException();
      }

      @Override
      public void writeLazy(byte[] value, int offset, int length) throws IOException {
        throw new UnsupportedOperationException();
      }

      @Override
      public void write(ByteBuffer value) throws IOException {
        throw new UnsupportedOperationException();
      }

      @Override
      public void writeLazy(ByteBuffer value) throws IOException {
        Arrays.fill(value.array(), value.arrayOffset(), value.arrayOffset() + value.limit(),
            (byte) 0);
      }
    };

    testString.writeTo(out);
    byte[] allZeros = new byte[testString.size()];
    assertTrue(CLASSNAME + ".writeTo() must grant access to underlying buffer",
        Arrays.equals(allZeros, backingBuffer.array()));
  }

  public void testNewOutput() throws IOException {
    ByteArrayOutputStream bos = new ByteArrayOutputStream();
    ByteString.Output output = ByteString.newOutput();
    testString.writeTo(output);
    assertEquals("Output Size returns correct result",
        output.size(), testString.size());
    output.writeTo(bos);
    assertTrue("Output.writeTo() must give back the same bytes",
        Arrays.equals(BYTES, bos.toByteArray()));

    // write the output stream to itself! This should cause it to double
    output.writeTo(output);
    assertEquals("Writing an output stream to itself is successful",
        testString.concat(testString), output.toByteString());

    output.reset();
    assertEquals("Output.reset() resets the output", 0, output.size());
    assertEquals("Output.reset() resets the output",
        EMPTY, output.toByteString());
  }

  public void testToString() {
    String testString = "I love unicode \u1234\u5678 characters";
    ByteString unicode = forString(testString);
    String roundTripString = unicode.toString(UTF_8);
    assertEquals(CLASSNAME + " unicode must match", testString, roundTripString);
  }

  public void testCharsetToString() {
    String testString = "I love unicode \u1234\u5678 characters";
    ByteString unicode = forString(testString);
    String roundTripString = unicode.toString(UTF_8);
    assertEquals(CLASSNAME + " unicode must match", testString, roundTripString);
  }

  public void testToString_returnsCanonicalEmptyString() {
    assertSame(CLASSNAME + " must be the same string references",
        EMPTY.toString(UTF_8),
        new NioByteString(ByteBuffer.wrap(new byte[0])).toString(UTF_8));
  }

  public void testToString_raisesException() {
    try {
      EMPTY.toString("invalid");
      fail("Should have thrown an exception.");
    } catch (UnsupportedEncodingException expected) {
      // This is success
    }

    try {
      testString.toString("invalid");
      fail("Should have thrown an exception.");
    } catch (UnsupportedEncodingException expected) {
      // This is success
    }
  }

  public void testEquals() {
    assertEquals(CLASSNAME + " must not equal null", false, testString.equals(null));
    assertEquals(CLASSNAME + " must equal self", testString, testString);
    assertFalse(CLASSNAME + " must not equal the empty string",
        testString.equals(EMPTY));
    assertEquals(CLASSNAME + " empty strings must be equal",
        EMPTY, testString.substring(55, 55));
    assertEquals(CLASSNAME + " must equal another string with the same value",
        testString, new NioByteString(backingBuffer));

    byte[] mungedBytes = mungedBytes();
    assertFalse(CLASSNAME + " must not equal every string with the same length",
        testString.equals(new NioByteString(ByteBuffer.wrap(mungedBytes))));
  }

  public void testEqualsLiteralByteString() {
    ByteString literal = ByteString.copyFrom(BYTES);
    assertEquals(CLASSNAME + " must equal LiteralByteString with same value", literal,
        testString);
    assertEquals(CLASSNAME + " must equal LiteralByteString with same value", testString,
        literal);
    assertFalse(CLASSNAME + " must not equal the empty string",
        testString.equals(ByteString.EMPTY));
    assertEquals(CLASSNAME + " empty strings must be equal",
        ByteString.EMPTY, testString.substring(55, 55));

    literal = ByteString.copyFrom(mungedBytes());
    assertFalse(CLASSNAME + " must not equal every LiteralByteString with the same length",
        testString.equals(literal));
    assertFalse(CLASSNAME + " must not equal every LiteralByteString with the same length",
        literal.equals(testString));
  }

  public void testEqualsRopeByteString() {
    ByteString p1 = ByteString.copyFrom(BYTES, 0, 5);
    ByteString p2 = ByteString.copyFrom(BYTES, 5, BYTES.length - 5);
    ByteString rope = p1.concat(p2);

    assertEquals(CLASSNAME + " must equal RopeByteString with same value", rope,
        testString);
    assertEquals(CLASSNAME + " must equal RopeByteString with same value", testString,
        rope);
    assertFalse(CLASSNAME + " must not equal the empty string",
        testString.equals(ByteString.EMPTY.concat(ByteString.EMPTY)));
    assertEquals(CLASSNAME + " empty strings must be equal",
        ByteString.EMPTY.concat(ByteString.EMPTY), testString.substring(55, 55));

    byte[] mungedBytes = mungedBytes();
    p1 = ByteString.copyFrom(mungedBytes, 0, 5);
    p2 = ByteString.copyFrom(mungedBytes, 5, mungedBytes.length - 5);
    rope = p1.concat(p2);
    assertFalse(CLASSNAME + " must not equal every RopeByteString with the same length",
        testString.equals(rope));
    assertFalse(CLASSNAME + " must not equal every RopeByteString with the same length",
        rope.equals(testString));
  }

  private byte[] mungedBytes() {
    byte[] mungedBytes = new byte[BYTES.length];
    System.arraycopy(BYTES, 0, mungedBytes, 0, BYTES.length);
    mungedBytes[mungedBytes.length - 5] = (byte) (mungedBytes[mungedBytes.length - 5] ^ 0xFF);
    return mungedBytes;
  }

  public void testHashCode() {
    int hash = testString.hashCode();
    assertEquals(CLASSNAME + " must have expected hashCode", EXPECTED_HASH, hash);
  }

  public void testPeekCachedHashCode() {
    ByteString newString = new NioByteString(backingBuffer);
    assertEquals(CLASSNAME + ".peekCachedHashCode() should return zero at first", 0,
        newString.peekCachedHashCode());
    newString.hashCode();
    assertEquals(CLASSNAME + ".peekCachedHashCode should return zero at first",
        EXPECTED_HASH, newString.peekCachedHashCode());
  }

  public void testPartialHash() {
    // partialHash() is more strenuously tested elsewhere by testing hashes of substrings.
    // This test would fail if the expected hash were 1.  It's not.
    int hash = testString.partialHash(testString.size(), 0, testString.size());
    assertEquals(CLASSNAME + ".partialHash() must yield expected hashCode",
        EXPECTED_HASH, hash);
  }

  public void testNewInput() throws IOException {
    InputStream input = testString.newInput();
    assertEquals("InputStream.available() returns correct value",
        testString.size(), input.available());
    boolean stillEqual = true;
    for (byte referenceByte : BYTES) {
      int expectedInt = (referenceByte & 0xFF);
      stillEqual = (expectedInt == input.read());
    }
    assertEquals("InputStream.available() returns correct value",
        0, input.available());
    assertTrue(CLASSNAME + " must give the same bytes from the InputStream", stillEqual);
    assertEquals(CLASSNAME + " InputStream must now be exhausted", -1, input.read());
  }

  public void testNewInput_skip() throws IOException {
    InputStream input = testString.newInput();
    int stringSize = testString.size();
    int nearEndIndex = stringSize * 2 / 3;
    long skipped1 = input.skip(nearEndIndex);
    assertEquals("InputStream.skip()", skipped1, nearEndIndex);
    assertEquals("InputStream.available()",
        stringSize - skipped1, input.available());
    assertTrue("InputStream.mark() is available", input.markSupported());
    input.mark(0);
    assertEquals("InputStream.skip(), read()",
        testString.byteAt(nearEndIndex) & 0xFF, input.read());
    assertEquals("InputStream.available()",
        stringSize - skipped1 - 1, input.available());
    long skipped2 = input.skip(stringSize);
    assertEquals("InputStream.skip() incomplete",
        skipped2, stringSize - skipped1 - 1);
    assertEquals("InputStream.skip(), no more input", 0, input.available());
    assertEquals("InputStream.skip(), no more input", -1, input.read());
    input.reset();
    assertEquals("InputStream.reset() succeded",
        stringSize - skipped1, input.available());
    assertEquals("InputStream.reset(), read()",
        testString.byteAt(nearEndIndex) & 0xFF, input.read());
  }

  public void testNewCodedInput() throws IOException {
    CodedInputStream cis = testString.newCodedInput();
    byte[] roundTripBytes = cis.readRawBytes(BYTES.length);
    assertTrue(CLASSNAME + " must give the same bytes back from the CodedInputStream",
        Arrays.equals(BYTES, roundTripBytes));
    assertTrue(CLASSNAME + " CodedInputStream must now be exhausted", cis.isAtEnd());
  }

  /**
   * Make sure we keep things simple when concatenating with empty. See also
   * {@link ByteStringTest#testConcat_empty()}.
   */
  public void testConcat_empty() {
    assertSame(CLASSNAME + " concatenated with empty must give " + CLASSNAME,
        testString.concat(EMPTY), testString);
    assertSame("empty concatenated with " + CLASSNAME + " must give " + CLASSNAME,
        EMPTY.concat(testString), testString);
  }

  public void testJavaSerialization() throws Exception {
    ByteArrayOutputStream out = new ByteArrayOutputStream();
    ObjectOutputStream oos = new ObjectOutputStream(out);
    oos.writeObject(testString);
    oos.close();
    byte[] pickled = out.toByteArray();
    InputStream in = new ByteArrayInputStream(pickled);
    ObjectInputStream ois = new ObjectInputStream(in);
    Object o = ois.readObject();
    assertTrue("Didn't get a ByteString back", o instanceof ByteString);
    assertEquals("Should get an equal ByteString back", testString, o);
  }

  private static ByteString forString(String str) {
    return new NioByteString(ByteBuffer.wrap(str.getBytes(UTF_8)));
  }
}
