/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.apache.beam.sdk.io.gcp.spanner;

import static org.junit.Assert.assertArrayEquals;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;

import com.google.auto.value.AutoValue;
import java.util.List;
import org.apache.beam.vendor.guava.v20_0.com.google.common.collect.ImmutableList;
import org.apache.beam.vendor.guava.v20_0.com.google.common.io.BaseEncoding;
import org.apache.beam.vendor.guava.v20_0.com.google.common.primitives.Bytes;
import org.apache.beam.vendor.guava.v20_0.com.google.common.primitives.UnsignedBytes;
import org.apache.beam.vendor.guava.v20_0.com.google.common.primitives.UnsignedInteger;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;

/** A set of unit tests to verify {@link OrderedCode}. */
@RunWith(JUnit4.class)
public class OrderedCodeTest {
  /** Data for a generic coding test case with known encoded outputs. */
  abstract static class CodingTestCase<T> {
    /** The test value. */
    abstract T value();

    /** Test value's encoding in increasing order (obtained from the C++ implementation). */
    abstract String increasingBytes();

    /** Test value's encoding in dencreasing order (obtained from the C++ implementation). */
    abstract String decreasingBytes();

    // Helper methods to implement in concrete classes.

    abstract byte[] encodeIncreasing();

    abstract byte[] encodeDecreasing();

    T decodeIncreasing() {
      return decodeIncreasing(new OrderedCode(bytesFromHexString(increasingBytes())));
    }

    T decodeDecreasing() {
      return decodeDecreasing(new OrderedCode(bytesFromHexString(decreasingBytes())));
    }

    abstract T decodeIncreasing(OrderedCode orderedCode);

    abstract T decodeDecreasing(OrderedCode orderedCode);
  }

  @AutoValue
  abstract static class UnsignedNumber extends CodingTestCase<Long> {
    @Override
    byte[] encodeIncreasing() {
      OrderedCode orderedCode = new OrderedCode();
      orderedCode.writeNumIncreasing(value());
      return orderedCode.getEncodedBytes();
    }

    @Override
    byte[] encodeDecreasing() {
      OrderedCode orderedCode = new OrderedCode();
      orderedCode.writeNumDecreasing(value());
      return orderedCode.getEncodedBytes();
    }

    @Override
    Long decodeIncreasing(OrderedCode orderedCode) {
      return orderedCode.readNumIncreasing();
    }

    @Override
    Long decodeDecreasing(OrderedCode orderedCode) {
      return orderedCode.readNumDecreasing();
    }

    private static UnsignedNumber testCase(
        long value, String increasingBytes, String decreasingBytes) {
      return new AutoValue_OrderedCodeTest_UnsignedNumber(value, increasingBytes, decreasingBytes);
    }

    /** Test cases for unsigned numbers, in increasing (unsigned) order by value. */
    private static final ImmutableList<UnsignedNumber> TEST_CASES =
        ImmutableList.of(
            testCase(0, "00", "ff"),
            testCase(1, "0101", "fefe"),
            testCase(33, "0121", "fede"),
            testCase(55000, "02d6d8", "fd2927"),
            testCase(Integer.MAX_VALUE, "047fffffff", "fb80000000"),
            testCase(Long.MAX_VALUE, "087fffffffffffffff", "f78000000000000000"),
            testCase(Long.MIN_VALUE, "088000000000000000", "f77fffffffffffffff"),
            testCase(-100, "08ffffffffffffff9c", "f70000000000000063"),
            testCase(-1, "08ffffffffffffffff", "f70000000000000000"));
  }

  @AutoValue
  abstract static class BytesTest extends CodingTestCase<String> {
    @Override
    byte[] encodeIncreasing() {
      OrderedCode orderedCode = new OrderedCode();
      orderedCode.writeBytes(bytesFromHexString(value()));
      return orderedCode.getEncodedBytes();
    }

    @Override
    byte[] encodeDecreasing() {
      OrderedCode orderedCode = new OrderedCode();
      orderedCode.writeBytesDecreasing(bytesFromHexString(value()));
      return orderedCode.getEncodedBytes();
    }

    @Override
    String decodeIncreasing(OrderedCode orderedCode) {
      return bytesToHexString(orderedCode.readBytes());
    }

    @Override
    String decodeDecreasing(OrderedCode orderedCode) {
      return bytesToHexString(orderedCode.readBytesDecreasing());
    }

    private static BytesTest testCase(
        String value, String increasingBytes, String decreasingBytes) {
      return new AutoValue_OrderedCodeTest_BytesTest(value, increasingBytes, decreasingBytes);
    }

    /** Test cases for byte arrays, in increasing order by value. */
    private static final ImmutableList<BytesTest> TEST_CASES =
        ImmutableList.of(
            testCase("", "0001", "fffe"),
            testCase("00", "00ff0001", "ff00fffe"),
            testCase("0000", "00ff00ff0001", "ff00ff00fffe"),
            testCase("0001", "00ff010001", "ff00fefffe"),
            testCase("0041", "00ff410001", "ff00befffe"),
            testCase("00ff", "00ffff000001", "ff0000fffffe"),
            testCase("01", "010001", "fefffe"),
            testCase("0100", "0100ff0001", "feff00fffe"),
            testCase("6f776c", "6f776c0001", "908893fffe"),
            testCase("ff", "ff000001", "00fffffe"),
            testCase("ff00", "ff0000ff0001", "00ffff00fffe"),
            testCase("ff01", "ff00010001", "00fffefffe"),
            testCase("ffff", "ff00ff000001", "00ff00fffffe"),
            testCase("ffffff", "ff00ff00ff000001", "00ff00ff00fffffe"));
  }

  @Test
  public void testUnsignedEncoding() {
    testEncoding(UnsignedNumber.TEST_CASES);
  }

  @Test
  public void testUnsignedDecoding() {
    testDecoding(UnsignedNumber.TEST_CASES);
  }

  @Test
  public void testUnsignedOrdering() {
    testOrdering(UnsignedNumber.TEST_CASES);
  }

  @Test
  public void testBytesEncoding() {
    testEncoding(BytesTest.TEST_CASES);
  }

  @Test
  public void testBytesDecoding() {
    testDecoding(BytesTest.TEST_CASES);
  }

  @Test
  public void testBytesOrdering() {
    testOrdering(BytesTest.TEST_CASES);
  }

  private void testEncoding(List<? extends CodingTestCase<?>> testCases) {
    for (CodingTestCase<?> testCase : testCases) {
      byte[] actualIncreasing = testCase.encodeIncreasing();
      byte[] expectedIncreasing = bytesFromHexString(testCase.increasingBytes());
      assertEquals(0, compare(actualIncreasing, expectedIncreasing));

      byte[] actualDecreasing = testCase.encodeDecreasing();
      byte[] expectedDecreasing = bytesFromHexString(testCase.decreasingBytes());
      assertEquals(0, compare(actualDecreasing, expectedDecreasing));
    }
  }

  private void testDecoding(List<? extends CodingTestCase<?>> testCases) {
    for (CodingTestCase<?> testCase : testCases) {
      assertEquals(testCase.value(), testCase.decodeIncreasing());
      assertEquals(testCase.value(), testCase.decodeDecreasing());
    }
  }

  private void testOrdering(List<? extends CodingTestCase<?>> testCases) {
    // This is verifiable by inspection of the C++ encodings, but it seems
    // worth checking explicitly
    for (int caseIndex = 0; caseIndex < testCases.size() - 1; caseIndex++) {
      byte[] encodedValue = testCases.get(caseIndex).encodeIncreasing();
      byte[] nextEncodedValue = testCases.get(caseIndex + 1).encodeIncreasing();
      assertTrue(compare(encodedValue, nextEncodedValue) < 0);

      encodedValue = testCases.get(caseIndex).encodeDecreasing();
      nextEncodedValue = testCases.get(caseIndex + 1).encodeDecreasing();
      assertTrue(compare(encodedValue, nextEncodedValue) > 0);
    }
  }

  @Test
  public void testWriteInfinity() {
    OrderedCode orderedCode = new OrderedCode();
    try {
      orderedCode.readInfinity();
      fail("Expected IllegalArgumentException.");
    } catch (IllegalArgumentException e) {
      // expected
    }
    orderedCode.writeInfinity();
    assertTrue(orderedCode.readInfinity());
    try {
      orderedCode.readInfinity();
      fail("Expected IllegalArgumentException.");
    } catch (IllegalArgumentException e) {
      // expected
    }
  }

  @Test
  public void testWriteInfinityDecreasing() {
    OrderedCode orderedCode = new OrderedCode();
    try {
      orderedCode.readInfinityDecreasing();
      fail("Expected IllegalArgumentException.");
    } catch (IllegalArgumentException e) {
      // expected
    }
    orderedCode.writeInfinityDecreasing();
    assertTrue(orderedCode.readInfinityDecreasing());
    try {
      orderedCode.readInfinityDecreasing();
      fail("Expected IllegalArgumentException.");
    } catch (IllegalArgumentException e) {
      // expected
    }
  }

  @Test
  public void testWriteBytes() {
    byte[] first = {'a', 'b', 'c'};
    byte[] second = {'d', 'e', 'f'};
    byte[] last = {'x', 'y', 'z'};
    OrderedCode orderedCode = new OrderedCode();
    orderedCode.writeBytes(first);
    byte[] firstEncoded = orderedCode.getEncodedBytes();
    assertArrayEquals(orderedCode.readBytes(), first);

    orderedCode.writeBytes(first);
    orderedCode.writeBytes(second);
    orderedCode.writeBytes(last);
    byte[] allEncoded = orderedCode.getEncodedBytes();
    assertArrayEquals(orderedCode.readBytes(), first);
    assertArrayEquals(orderedCode.readBytes(), second);
    assertArrayEquals(orderedCode.readBytes(), last);

    orderedCode = new OrderedCode(firstEncoded);
    orderedCode.writeBytes(second);
    orderedCode.writeBytes(last);
    assertArrayEquals(orderedCode.getEncodedBytes(), allEncoded);
    assertArrayEquals(orderedCode.readBytes(), first);
    assertArrayEquals(orderedCode.readBytes(), second);
    assertArrayEquals(orderedCode.readBytes(), last);

    orderedCode = new OrderedCode(allEncoded);
    assertArrayEquals(orderedCode.readBytes(), first);
    assertArrayEquals(orderedCode.readBytes(), second);
    assertArrayEquals(orderedCode.readBytes(), last);
  }

  @Test
  public void testWriteBytesDecreasing() {
    byte[] first = {'a', 'b', 'c'};
    byte[] second = {'d', 'e', 'f'};
    byte[] last = {'x', 'y', 'z'};
    OrderedCode orderedCode = new OrderedCode();
    orderedCode.writeBytesDecreasing(first);
    byte[] firstEncoded = orderedCode.getEncodedBytes();
    assertArrayEquals(orderedCode.readBytesDecreasing(), first);

    orderedCode.writeBytesDecreasing(first);
    orderedCode.writeBytesDecreasing(second);
    orderedCode.writeBytesDecreasing(last);
    byte[] allEncoded = orderedCode.getEncodedBytes();
    assertArrayEquals(orderedCode.readBytesDecreasing(), first);
    assertArrayEquals(orderedCode.readBytesDecreasing(), second);
    assertArrayEquals(orderedCode.readBytesDecreasing(), last);

    orderedCode = new OrderedCode(firstEncoded);
    orderedCode.writeBytesDecreasing(second);
    orderedCode.writeBytesDecreasing(last);
    assertArrayEquals(orderedCode.getEncodedBytes(), allEncoded);
    assertArrayEquals(orderedCode.readBytesDecreasing(), first);
    assertArrayEquals(orderedCode.readBytesDecreasing(), second);
    assertArrayEquals(orderedCode.readBytesDecreasing(), last);

    orderedCode = new OrderedCode(allEncoded);
    assertArrayEquals(orderedCode.readBytesDecreasing(), first);
    assertArrayEquals(orderedCode.readBytesDecreasing(), second);
    assertArrayEquals(orderedCode.readBytesDecreasing(), last);
  }

  @Test
  public void testWriteNumIncreasing() {
    OrderedCode orderedCode = new OrderedCode();
    orderedCode.writeNumIncreasing(0);
    orderedCode.writeNumIncreasing(1);
    orderedCode.writeNumIncreasing(Long.MIN_VALUE);
    orderedCode.writeNumIncreasing(Long.MAX_VALUE);
    assertEquals(0, orderedCode.readNumIncreasing());
    assertEquals(1, orderedCode.readNumIncreasing());
    assertEquals(Long.MIN_VALUE, orderedCode.readNumIncreasing());
    assertEquals(Long.MAX_VALUE, orderedCode.readNumIncreasing());
  }

  @Test
  public void testWriteNumIncreasing_unsignedInt() {
    OrderedCode orderedCode = new OrderedCode();
    orderedCode.writeNumIncreasing(UnsignedInteger.fromIntBits(0));
    orderedCode.writeNumIncreasing(UnsignedInteger.fromIntBits(1));
    orderedCode.writeNumIncreasing(UnsignedInteger.fromIntBits(Integer.MIN_VALUE));
    orderedCode.writeNumIncreasing(UnsignedInteger.fromIntBits(Integer.MAX_VALUE));
    assertEquals(0, orderedCode.readNumIncreasing());
    assertEquals(1, orderedCode.readNumIncreasing());
    assertEquals((long) Integer.MAX_VALUE + 1L, orderedCode.readNumIncreasing());
    assertEquals(Integer.MAX_VALUE, orderedCode.readNumIncreasing());
  }

  @Test
  public void testWriteNumDecreasing() {
    OrderedCode orderedCode = new OrderedCode();
    orderedCode.writeNumDecreasing(0);
    orderedCode.writeNumDecreasing(1);
    orderedCode.writeNumDecreasing(Long.MIN_VALUE);
    orderedCode.writeNumDecreasing(Long.MAX_VALUE);
    assertEquals(0, orderedCode.readNumDecreasing());
    assertEquals(1, orderedCode.readNumDecreasing());
    assertEquals(Long.MIN_VALUE, orderedCode.readNumDecreasing());
    assertEquals(Long.MAX_VALUE, orderedCode.readNumDecreasing());
  }

  @Test
  public void testWriteNumDecreasing_unsignedInt() {
    OrderedCode orderedCode = new OrderedCode();
    orderedCode.writeNumDecreasing(UnsignedInteger.fromIntBits(0));
    orderedCode.writeNumDecreasing(UnsignedInteger.fromIntBits(1));
    orderedCode.writeNumDecreasing(UnsignedInteger.fromIntBits(Integer.MIN_VALUE));
    orderedCode.writeNumDecreasing(UnsignedInteger.fromIntBits(Integer.MAX_VALUE));
    assertEquals(0, orderedCode.readNumDecreasing());
    assertEquals(1, orderedCode.readNumDecreasing());
    assertEquals((long) Integer.MAX_VALUE + 1L, orderedCode.readNumDecreasing());
    assertEquals(Integer.MAX_VALUE, orderedCode.readNumDecreasing());
  }

  /**
   * Assert that encoding the specified long via {@link OrderedCode#writeSignedNumIncreasing(long)}
   * results in the bytes represented by the specified string of hex digits. E.g.
   * assertSignedNumIncreasingEncodingEquals("3fbf", -65) asserts that -65 is encoded as { (byte)
   * 0x3f, (byte) 0xbf }.
   */
  private static void assertSignedNumIncreasingEncodingEquals(
      String expectedHexEncoding, long num) {
    OrderedCode orderedCode = new OrderedCode();
    orderedCode.writeSignedNumIncreasing(num);
    assertEquals(
        "Unexpected encoding for " + num,
        expectedHexEncoding,
        bytesToHexString(orderedCode.getEncodedBytes()));
  }

  /**
   * Assert that encoding various long values via {@link OrderedCode#writeSignedNumIncreasing(long)}
   * produces the expected bytes. Expected byte sequences were generated via the c++ (authoritative)
   * implementation of OrderedCode::WriteSignedNumIncreasing.
   */
  @Test
  public void testSignedNumIncreasing_write() {
    assertSignedNumIncreasingEncodingEquals("003f8000000000000000", Long.MIN_VALUE);
    assertSignedNumIncreasingEncodingEquals("003f8000000000000001", Long.MIN_VALUE + 1);
    assertSignedNumIncreasingEncodingEquals("077fffffff", Integer.MIN_VALUE - 1L);
    assertSignedNumIncreasingEncodingEquals("0780000000", Integer.MIN_VALUE);
    assertSignedNumIncreasingEncodingEquals("0780000001", Integer.MIN_VALUE + 1);
    assertSignedNumIncreasingEncodingEquals("3fbf", -65);
    assertSignedNumIncreasingEncodingEquals("40", -64);
    assertSignedNumIncreasingEncodingEquals("41", -63);
    assertSignedNumIncreasingEncodingEquals("7d", -3);
    assertSignedNumIncreasingEncodingEquals("7e", -2);
    assertSignedNumIncreasingEncodingEquals("7f", -1);
    assertSignedNumIncreasingEncodingEquals("80", 0);
    assertSignedNumIncreasingEncodingEquals("81", 1);
    assertSignedNumIncreasingEncodingEquals("82", 2);
    assertSignedNumIncreasingEncodingEquals("83", 3);
    assertSignedNumIncreasingEncodingEquals("bf", 63);
    assertSignedNumIncreasingEncodingEquals("c040", 64);
    assertSignedNumIncreasingEncodingEquals("c041", 65);
    assertSignedNumIncreasingEncodingEquals("f87ffffffe", Integer.MAX_VALUE - 1);
    assertSignedNumIncreasingEncodingEquals("f87fffffff", Integer.MAX_VALUE);
    assertSignedNumIncreasingEncodingEquals("f880000000", Integer.MAX_VALUE + 1L);
    assertSignedNumIncreasingEncodingEquals("ffc07ffffffffffffffe", Long.MAX_VALUE - 1);
    assertSignedNumIncreasingEncodingEquals("ffc07fffffffffffffff", Long.MAX_VALUE);
  }

  /**
   * Convert a string of hex digits (e.g. "3fbf") to a byte[] (e.g. { (byte) 0x3f, (byte) 0xbf }).
   */
  private static byte[] bytesFromHexString(String hexDigits) {
    return BaseEncoding.base16().lowerCase().decode(hexDigits);
  }

  /**
   * Convert a byte[] (e.g. { (byte) 0x3f, (byte) 0xbf }) to a string of hex digits (e.g. "3fbf").
   */
  private static String bytesToHexString(byte[] bytes) {
    return BaseEncoding.base16().lowerCase().encode(bytes);
  }

  /**
   * Assert that decoding (via {@link OrderedCode#readSignedNumIncreasing()}) the bytes represented
   * by the specified string of hex digits results in the expected long value. E.g.
   * assertDecodedSignedNumIncreasingEquals(-65, "3fbf") asserts that the byte array { (byte) 0x3f,
   * (byte) 0xbf } is decoded as -65.
   */
  private static void assertDecodedSignedNumIncreasingEquals(
      long expectedNum, String encodedHexString) {
    OrderedCode orderedCode = new OrderedCode(bytesFromHexString(encodedHexString));
    assertEquals(
        "Unexpected value when decoding 0x" + encodedHexString,
        expectedNum,
        orderedCode.readSignedNumIncreasing());
    assertFalse(
        "Unexpected encoded bytes remain after decoding 0x" + encodedHexString,
        orderedCode.hasRemainingEncodedBytes());
  }

  /**
   * Assert that decoding various sequences of bytes via {@link
   * OrderedCode#readSignedNumIncreasing()} produces the expected long value. Input byte sequences
   * were generated via the c++ (authoritative) implementation of
   * OrderedCode::WriteSignedNumIncreasing.
   */
  @Test
  public void testSignedNumIncreasing_read() {
    assertDecodedSignedNumIncreasingEquals(Long.MIN_VALUE, "003f8000000000000000");
    assertDecodedSignedNumIncreasingEquals(Long.MIN_VALUE + 1, "003f8000000000000001");
    assertDecodedSignedNumIncreasingEquals(Integer.MIN_VALUE - 1L, "077fffffff");
    assertDecodedSignedNumIncreasingEquals(Integer.MIN_VALUE, "0780000000");
    assertDecodedSignedNumIncreasingEquals(Integer.MIN_VALUE + 1, "0780000001");
    assertDecodedSignedNumIncreasingEquals(-65, "3fbf");
    assertDecodedSignedNumIncreasingEquals(-64, "40");
    assertDecodedSignedNumIncreasingEquals(-63, "41");
    assertDecodedSignedNumIncreasingEquals(-3, "7d");
    assertDecodedSignedNumIncreasingEquals(-2, "7e");
    assertDecodedSignedNumIncreasingEquals(-1, "7f");
    assertDecodedSignedNumIncreasingEquals(0, "80");
    assertDecodedSignedNumIncreasingEquals(1, "81");
    assertDecodedSignedNumIncreasingEquals(2, "82");
    assertDecodedSignedNumIncreasingEquals(3, "83");
    assertDecodedSignedNumIncreasingEquals(63, "bf");
    assertDecodedSignedNumIncreasingEquals(64, "c040");
    assertDecodedSignedNumIncreasingEquals(65, "c041");
    assertDecodedSignedNumIncreasingEquals(Integer.MAX_VALUE - 1, "f87ffffffe");
    assertDecodedSignedNumIncreasingEquals(Integer.MAX_VALUE, "f87fffffff");
    assertDecodedSignedNumIncreasingEquals(Integer.MAX_VALUE + 1L, "f880000000");
    assertDecodedSignedNumIncreasingEquals(Long.MAX_VALUE - 1, "ffc07ffffffffffffffe");
    assertDecodedSignedNumIncreasingEquals(Long.MAX_VALUE, "ffc07fffffffffffffff");
  }

  /**
   * Assert that encoding (via {@link OrderedCode#writeSignedNumIncreasing(long)}) the specified
   * long value and then decoding (via {@link OrderedCode#readSignedNumIncreasing()}) results in the
   * original value.
   */
  private static void assertSignedNumIncreasingWriteAndReadIsLossless(long num) {
    OrderedCode orderedCode = new OrderedCode();
    orderedCode.writeSignedNumIncreasing(num);
    assertEquals(
        "Unexpected result when decoding writeSignedNumIncreasing(" + num + ")",
        num,
        orderedCode.readSignedNumIncreasing());
    assertFalse(
        "Unexpected remaining encoded bytes after decoding " + num,
        orderedCode.hasRemainingEncodedBytes());
  }

  /**
   * Assert that for various long values, encoding (via {@link
   * OrderedCode#writeSignedNumIncreasing(long)}) and then decoding (via {@link
   * OrderedCode#readSignedNumIncreasing()}) results in the original value.
   */
  @Test
  public void testSignedNumIncreasing_writeAndRead() {
    assertSignedNumIncreasingWriteAndReadIsLossless(Long.MIN_VALUE);
    assertSignedNumIncreasingWriteAndReadIsLossless(Long.MIN_VALUE + 1);
    assertSignedNumIncreasingWriteAndReadIsLossless(Integer.MIN_VALUE - 1L);
    assertSignedNumIncreasingWriteAndReadIsLossless(Integer.MIN_VALUE);
    assertSignedNumIncreasingWriteAndReadIsLossless(Integer.MIN_VALUE + 1);
    assertSignedNumIncreasingWriteAndReadIsLossless(-65);
    assertSignedNumIncreasingWriteAndReadIsLossless(-64);
    assertSignedNumIncreasingWriteAndReadIsLossless(-63);
    assertSignedNumIncreasingWriteAndReadIsLossless(-3);
    assertSignedNumIncreasingWriteAndReadIsLossless(-2);
    assertSignedNumIncreasingWriteAndReadIsLossless(-1);
    assertSignedNumIncreasingWriteAndReadIsLossless(0);
    assertSignedNumIncreasingWriteAndReadIsLossless(1);
    assertSignedNumIncreasingWriteAndReadIsLossless(2);
    assertSignedNumIncreasingWriteAndReadIsLossless(3);
    assertSignedNumIncreasingWriteAndReadIsLossless(63);
    assertSignedNumIncreasingWriteAndReadIsLossless(64);
    assertSignedNumIncreasingWriteAndReadIsLossless(65);
    assertSignedNumIncreasingWriteAndReadIsLossless(Integer.MAX_VALUE - 1);
    assertSignedNumIncreasingWriteAndReadIsLossless(Integer.MAX_VALUE);
    assertSignedNumIncreasingWriteAndReadIsLossless(Integer.MAX_VALUE + 1L);
    assertSignedNumIncreasingWriteAndReadIsLossless(Long.MAX_VALUE - 1);
    assertSignedNumIncreasingWriteAndReadIsLossless(Long.MAX_VALUE);
  }

  /**
   * Assert that encoding (via {@link OrderedCode#writeSignedNumDecreasing(long)}) the specified
   * long value and then decoding (via {@link OrderedCode#readSignedNumDecreasing()}) results in the
   * original value.
   */
  private static void assertSignedNumDecreasingWriteAndReadIsLossless(long num) {
    OrderedCode orderedCode = new OrderedCode();
    orderedCode.writeSignedNumDecreasing(num);
    assertEquals(
        "Unexpected result when decoding writeSignedNumDecreasing(" + num + ")",
        num,
        orderedCode.readSignedNumDecreasing());
    assertFalse(
        "Unexpected remaining encoded bytes after decoding " + num,
        orderedCode.hasRemainingEncodedBytes());
  }

  /**
   * Assert that for various long values, encoding (via {@link
   * OrderedCode#writeSignedNumDecreasing(long)}) and then decoding (via {@link
   * OrderedCode#readSignedNumDecreasing()}) results in the original value.
   */
  @Test
  public void testSignedNumDecreasing_writeAndRead() {
    assertSignedNumDecreasingWriteAndReadIsLossless(Long.MIN_VALUE);
    assertSignedNumDecreasingWriteAndReadIsLossless(Long.MIN_VALUE + 1);
    assertSignedNumDecreasingWriteAndReadIsLossless(Integer.MIN_VALUE - 1L);
    assertSignedNumDecreasingWriteAndReadIsLossless(Integer.MIN_VALUE);
    assertSignedNumDecreasingWriteAndReadIsLossless(Integer.MIN_VALUE + 1);
    assertSignedNumDecreasingWriteAndReadIsLossless(-65);
    assertSignedNumDecreasingWriteAndReadIsLossless(-64);
    assertSignedNumDecreasingWriteAndReadIsLossless(-63);
    assertSignedNumDecreasingWriteAndReadIsLossless(-3);
    assertSignedNumDecreasingWriteAndReadIsLossless(-2);
    assertSignedNumDecreasingWriteAndReadIsLossless(-1);
    assertSignedNumDecreasingWriteAndReadIsLossless(0);
    assertSignedNumDecreasingWriteAndReadIsLossless(1);
    assertSignedNumDecreasingWriteAndReadIsLossless(2);
    assertSignedNumDecreasingWriteAndReadIsLossless(3);
    assertSignedNumDecreasingWriteAndReadIsLossless(63);
    assertSignedNumDecreasingWriteAndReadIsLossless(64);
    assertSignedNumDecreasingWriteAndReadIsLossless(65);
    assertSignedNumDecreasingWriteAndReadIsLossless(Integer.MAX_VALUE - 1);
    assertSignedNumDecreasingWriteAndReadIsLossless(Integer.MAX_VALUE);
    assertSignedNumDecreasingWriteAndReadIsLossless(Integer.MAX_VALUE + 1L);
    assertSignedNumDecreasingWriteAndReadIsLossless(Long.MAX_VALUE - 1);
    assertSignedNumDecreasingWriteAndReadIsLossless(Long.MAX_VALUE);
  }

  /** Ensures that numbers encoded as "decreasing" do indeed sort in reverse order. */
  @Test
  public void testDecreasing() {
    OrderedCode orderedCode = new OrderedCode();
    orderedCode.writeSignedNumDecreasing(10L);
    byte[] ten = orderedCode.getEncodedBytes();
    orderedCode = new OrderedCode();
    orderedCode.writeSignedNumDecreasing(20L);
    byte[] twenty = orderedCode.getEncodedBytes();
    // In decreasing order, twenty preceeds ten.
    assertTrue(compare(twenty, ten) < 0);
  }

  @Test
  public void testLog2Floor_Positive() {
    OrderedCode orderedCode = new OrderedCode();
    assertEquals(0, orderedCode.log2Floor(1));
    assertEquals(1, orderedCode.log2Floor(2));
    assertEquals(1, orderedCode.log2Floor(3));
    assertEquals(2, orderedCode.log2Floor(4));
    assertEquals(5, orderedCode.log2Floor(63));
    assertEquals(6, orderedCode.log2Floor(64));
    assertEquals(62, orderedCode.log2Floor(Long.MAX_VALUE));
  }

  /**
   * OrderedCode.log2Floor(long) is defined to return -1 given an input of zero (because that's what
   * Bits::Log2Floor64(uint64) does).
   */
  @Test
  public void testLog2Floor_zero() {
    OrderedCode orderedCode = new OrderedCode();
    assertEquals(-1, orderedCode.log2Floor(0));
  }

  @Test
  public void testLog2Floor_negative() {
    OrderedCode orderedCode = new OrderedCode();
    try {
      orderedCode.log2Floor(-1);
      fail("Expected an IllegalArgumentException.");
    } catch (IllegalArgumentException expected) {
      // Expected!
    }
  }

  @Test
  public void testGetSignedEncodingLength() {
    OrderedCode orderedCode = new OrderedCode();
    assertEquals(10, orderedCode.getSignedEncodingLength(Long.MIN_VALUE));
    assertEquals(10, orderedCode.getSignedEncodingLength(~(1L << 62)));
    assertEquals(9, orderedCode.getSignedEncodingLength(~(1L << 62) + 1));
    assertEquals(3, orderedCode.getSignedEncodingLength(-8193));
    assertEquals(2, orderedCode.getSignedEncodingLength(-8192));
    assertEquals(2, orderedCode.getSignedEncodingLength(-65));
    assertEquals(1, orderedCode.getSignedEncodingLength(-64));
    assertEquals(1, orderedCode.getSignedEncodingLength(-2));
    assertEquals(1, orderedCode.getSignedEncodingLength(-1));
    assertEquals(1, orderedCode.getSignedEncodingLength(0));
    assertEquals(1, orderedCode.getSignedEncodingLength(1));
    assertEquals(1, orderedCode.getSignedEncodingLength(63));
    assertEquals(2, orderedCode.getSignedEncodingLength(64));
    assertEquals(2, orderedCode.getSignedEncodingLength(8191));
    assertEquals(3, orderedCode.getSignedEncodingLength(8192));
    assertEquals(9, orderedCode.getSignedEncodingLength(1L << 62) - 1);
    assertEquals(10, orderedCode.getSignedEncodingLength(1L << 62));
    assertEquals(10, orderedCode.getSignedEncodingLength(Long.MAX_VALUE));
  }

  @Test
  public void testWriteTrailingBytes() {
    byte[] escapeChars =
        new byte[] {
          OrderedCode.ESCAPE1,
          OrderedCode.NULL_CHARACTER,
          OrderedCode.SEPARATOR,
          OrderedCode.ESCAPE2,
          OrderedCode.INFINITY,
          OrderedCode.FF_CHARACTER
        };
    byte[] anotherArray = new byte[] {'a', 'b', 'c', 'd', 'e'};

    OrderedCode orderedCode = new OrderedCode();
    orderedCode.writeTrailingBytes(escapeChars);
    assertArrayEquals(orderedCode.getEncodedBytes(), escapeChars);
    assertArrayEquals(orderedCode.readTrailingBytes(), escapeChars);
    try {
      orderedCode.readInfinity();
      fail("Expected IllegalArgumentException.");
    } catch (IllegalArgumentException e) {
      // expected
    }

    orderedCode = new OrderedCode();
    orderedCode.writeTrailingBytes(anotherArray);
    assertArrayEquals(orderedCode.getEncodedBytes(), anotherArray);
    assertArrayEquals(orderedCode.readTrailingBytes(), anotherArray);
  }

  @Test
  public void testMixedWrite() {
    byte[] first = {'a', 'b', 'c'};
    byte[] second = {'d', 'e', 'f'};
    byte[] last = {'x', 'y', 'z'};
    byte[] escapeChars =
        new byte[] {
          OrderedCode.ESCAPE1,
          OrderedCode.NULL_CHARACTER,
          OrderedCode.SEPARATOR,
          OrderedCode.ESCAPE2,
          OrderedCode.INFINITY,
          OrderedCode.FF_CHARACTER
        };

    OrderedCode orderedCode = new OrderedCode();
    orderedCode.writeBytes(first);
    orderedCode.writeBytes(second);
    orderedCode.writeBytes(last);
    orderedCode.writeInfinity();
    orderedCode.writeNumIncreasing(0);
    orderedCode.writeNumIncreasing(1);
    orderedCode.writeNumIncreasing(Long.MIN_VALUE);
    orderedCode.writeNumIncreasing(Long.MAX_VALUE);
    orderedCode.writeSignedNumIncreasing(0);
    orderedCode.writeSignedNumIncreasing(1);
    orderedCode.writeSignedNumIncreasing(Long.MIN_VALUE);
    orderedCode.writeSignedNumIncreasing(Long.MAX_VALUE);
    orderedCode.writeTrailingBytes(escapeChars);
    byte[] allEncoded = orderedCode.getEncodedBytes();
    assertArrayEquals(orderedCode.readBytes(), first);
    assertArrayEquals(orderedCode.readBytes(), second);
    assertFalse(orderedCode.readInfinity());
    assertArrayEquals(orderedCode.readBytes(), last);
    assertTrue(orderedCode.readInfinity());
    assertEquals(0, orderedCode.readNumIncreasing());
    assertEquals(1, orderedCode.readNumIncreasing());
    assertFalse(orderedCode.readInfinity());
    assertEquals(Long.MIN_VALUE, orderedCode.readNumIncreasing());
    assertEquals(Long.MAX_VALUE, orderedCode.readNumIncreasing());
    assertEquals(0, orderedCode.readSignedNumIncreasing());
    assertEquals(1, orderedCode.readSignedNumIncreasing());
    assertFalse(orderedCode.readInfinity());
    assertEquals(Long.MIN_VALUE, orderedCode.readSignedNumIncreasing());
    assertEquals(Long.MAX_VALUE, orderedCode.readSignedNumIncreasing());
    assertArrayEquals(orderedCode.getEncodedBytes(), escapeChars);
    assertArrayEquals(orderedCode.readTrailingBytes(), escapeChars);

    orderedCode = new OrderedCode(allEncoded);
    assertArrayEquals(orderedCode.readBytes(), first);
    assertArrayEquals(orderedCode.readBytes(), second);
    assertFalse(orderedCode.readInfinity());
    assertArrayEquals(orderedCode.readBytes(), last);
    assertTrue(orderedCode.readInfinity());
    assertEquals(0, orderedCode.readNumIncreasing());
    assertEquals(1, orderedCode.readNumIncreasing());
    assertFalse(orderedCode.readInfinity());
    assertEquals(Long.MIN_VALUE, orderedCode.readNumIncreasing());
    assertEquals(Long.MAX_VALUE, orderedCode.readNumIncreasing());
    assertEquals(0, orderedCode.readSignedNumIncreasing());
    assertEquals(1, orderedCode.readSignedNumIncreasing());
    assertFalse(orderedCode.readInfinity());
    assertEquals(Long.MIN_VALUE, orderedCode.readSignedNumIncreasing());
    assertEquals(Long.MAX_VALUE, orderedCode.readSignedNumIncreasing());
    assertArrayEquals(orderedCode.getEncodedBytes(), escapeChars);
    assertArrayEquals(orderedCode.readTrailingBytes(), escapeChars);
  }

  @Test
  public void testEdgeCases() {
    byte[] ffChar = {OrderedCode.FF_CHARACTER};
    byte[] nullChar = {OrderedCode.NULL_CHARACTER};

    byte[] separatorEncoded = {OrderedCode.ESCAPE1, OrderedCode.SEPARATOR};
    byte[] ffCharEncoded = {OrderedCode.ESCAPE1, OrderedCode.NULL_CHARACTER};
    byte[] nullCharEncoded = {OrderedCode.ESCAPE2, OrderedCode.FF_CHARACTER};
    byte[] infinityEncoded = {OrderedCode.ESCAPE2, OrderedCode.INFINITY};

    OrderedCode orderedCode = new OrderedCode();
    orderedCode.writeBytes(ffChar);
    orderedCode.writeBytes(nullChar);
    orderedCode.writeInfinity();
    assertArrayEquals(
        orderedCode.getEncodedBytes(),
        Bytes.concat(
            ffCharEncoded, separatorEncoded, nullCharEncoded, separatorEncoded, infinityEncoded));
    assertArrayEquals(orderedCode.readBytes(), ffChar);
    assertArrayEquals(orderedCode.readBytes(), nullChar);
    assertTrue(orderedCode.readInfinity());

    orderedCode = new OrderedCode(Bytes.concat(ffCharEncoded, separatorEncoded));
    assertArrayEquals(orderedCode.readBytes(), ffChar);

    orderedCode = new OrderedCode(Bytes.concat(nullCharEncoded, separatorEncoded));
    assertArrayEquals(orderedCode.readBytes(), nullChar);

    byte[] invalidEncodingForRead = {
      OrderedCode.ESCAPE2, OrderedCode.ESCAPE2, OrderedCode.ESCAPE1, OrderedCode.SEPARATOR
    };
    orderedCode = new OrderedCode(invalidEncodingForRead);
    try {
      orderedCode.readBytes();
      fail("Should have failed.");
    } catch (Exception e) {
      // Expected
    }
    assertTrue(orderedCode.hasRemainingEncodedBytes());
  }

  @Test
  public void testHasRemainingEncodedBytes() {
    byte[] bytes = {'a', 'b', 'c'};
    long number = 12345;

    // Empty
    OrderedCode orderedCode = new OrderedCode();
    assertFalse(orderedCode.hasRemainingEncodedBytes());

    // First and only field of each type.
    orderedCode.writeBytes(bytes);
    assertTrue(orderedCode.hasRemainingEncodedBytes());
    assertArrayEquals(orderedCode.readBytes(), bytes);
    assertFalse(orderedCode.hasRemainingEncodedBytes());

    orderedCode.writeNumIncreasing(number);
    assertTrue(orderedCode.hasRemainingEncodedBytes());
    assertEquals(orderedCode.readNumIncreasing(), number);
    assertFalse(orderedCode.hasRemainingEncodedBytes());

    orderedCode.writeSignedNumIncreasing(number);
    assertTrue(orderedCode.hasRemainingEncodedBytes());
    assertEquals(orderedCode.readSignedNumIncreasing(), number);
    assertFalse(orderedCode.hasRemainingEncodedBytes());

    orderedCode.writeInfinity();
    assertTrue(orderedCode.hasRemainingEncodedBytes());
    assertTrue(orderedCode.readInfinity());
    assertFalse(orderedCode.hasRemainingEncodedBytes());

    orderedCode.writeTrailingBytes(bytes);
    assertTrue(orderedCode.hasRemainingEncodedBytes());
    assertArrayEquals(orderedCode.readTrailingBytes(), bytes);
    assertFalse(orderedCode.hasRemainingEncodedBytes());

    // Two fields of same type.
    orderedCode.writeBytes(bytes);
    orderedCode.writeBytes(bytes);
    assertTrue(orderedCode.hasRemainingEncodedBytes());
    assertArrayEquals(orderedCode.readBytes(), bytes);
    assertArrayEquals(orderedCode.readBytes(), bytes);
    assertFalse(orderedCode.hasRemainingEncodedBytes());
  }

  @Test
  public void testOrderingInfinity() {
    OrderedCode inf = new OrderedCode();
    inf.writeInfinity();

    OrderedCode negInf = new OrderedCode();
    negInf.writeInfinityDecreasing();

    OrderedCode longValue = new OrderedCode();
    longValue.writeSignedNumIncreasing(1);

    assertTrue(compare(inf.getEncodedBytes(), negInf.getEncodedBytes()) > 0);
    assertTrue(compare(longValue.getEncodedBytes(), negInf.getEncodedBytes()) > 0);
    assertTrue(compare(inf.getEncodedBytes(), longValue.getEncodedBytes()) > 0);
  }

  private int compare(byte[] bytes1, byte[] bytes2) {
    return UnsignedBytes.lexicographicalComparator().compare(bytes1, bytes2);
  }
}
