/*
 * 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.v26_0_jre.com.google.common.collect.ImmutableList;
import org.apache.beam.vendor.guava.v26_0_jre.com.google.common.io.BaseEncoding;
import org.apache.beam.vendor.guava.v26_0_jre.com.google.common.primitives.Bytes;
import org.apache.beam.vendor.guava.v26_0_jre.com.google.common.primitives.UnsignedBytes;
import org.apache.beam.vendor.guava.v26_0_jre.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);
  }
}
