/*
 * 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.tuweni.bytes;

import static com.google.common.base.Preconditions.checkArgument;
import static com.google.common.base.Preconditions.checkElementIndex;
import static com.google.common.base.Preconditions.checkNotNull;
import static java.lang.String.format;
import static java.nio.ByteOrder.BIG_ENDIAN;

import java.io.IOException;
import java.math.BigInteger;
import java.nio.BufferOverflowException;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.ReadOnlyBufferException;
import java.security.MessageDigest;
import java.security.SecureRandom;
import java.util.Arrays;
import java.util.Base64;
import java.util.Random;

import io.netty.buffer.ByteBuf;
import io.vertx.core.buffer.Buffer;

/**
 * A value made of bytes.
 *
 * <p>
 * This interface makes no thread-safety guarantee, and a {@link Bytes} value is generally not thread safe. However,
 * specific implementations may be thread-safe. For instance, the value returned by {@link #copy} is guaranteed to be
 * thread-safe as it is immutable.
 */
public interface Bytes extends Comparable<Bytes> {

  /**
   * The empty value (with 0 bytes).
   */
  Bytes EMPTY = wrap(new byte[0]);

  /**
   * Wrap the provided byte array as a {@link Bytes} value.
   *
   * <p>
   * Note that value is not copied and thus any future update to {@code value} will be reflected in the returned value.
   *
   * @param value The value to wrap.
   * @return A {@link Bytes} value wrapping {@code value}.
   */
  static Bytes wrap(byte[] value) {
    return wrap(value, 0, value.length);
  }

  /**
   * Wrap a slice of a byte array as a {@link Bytes} value.
   *
   * <p>
   * Note that value is not copied and thus any future update to {@code value} within the slice will be reflected in the
   * returned value.
   *
   * @param value The value to wrap.
   * @param offset The index (inclusive) in {@code value} of the first byte exposed by the returned value. In other
   *        words, you will have {@code wrap(value, o, l).get(0) == value[o]}.
   * @param length The length of the resulting value.
   * @return A {@link Bytes} value that expose the bytes of {@code value} from {@code offset} (inclusive) to
   *         {@code offset + length} (exclusive).
   * @throws IndexOutOfBoundsException if {@code offset &lt; 0 || (value.length > 0 && offset >=
   *     value.length)}.
   * @throws IllegalArgumentException if {@code length &lt; 0 || offset + length > value.length}.
   */
  static Bytes wrap(byte[] value, int offset, int length) {
    checkNotNull(value);
    if (length == 32) {
      return new ArrayWrappingBytes32(value, offset);
    }
    return new ArrayWrappingBytes(value, offset, length);
  }

  /**
   * Wrap a list of other values into a concatenated view.
   *
   * <p>
   * Note that the values are not copied and thus any future update to the values will be reflected in the returned
   * value. If copying the inputs is desired, use {@link #concatenate(Bytes...)}.
   *
   * @param values The values to wrap.
   * @return A value representing a view over the concatenation of all {@code values}.
   * @throws IllegalArgumentException if the result overflows an int.
   */
  static Bytes wrap(Bytes... values) {
    return ConcatenatedBytes.wrap(values);
  }

  /**
   * Create a value containing the concatenation of the values provided.
   *
   * @param values The values to copy and concatenate.
   * @return A value containing the result of concatenating the value from {@code values} in their provided order.
   * @throws IllegalArgumentException if the result overflows an int.
   */
  static Bytes concatenate(Bytes... values) {
    if (values.length == 0) {
      return EMPTY;
    }

    int size;
    try {
      size = Arrays.stream(values).mapToInt(Bytes::size).reduce(0, Math::addExact);
    } catch (ArithmeticException e) {
      throw new IllegalArgumentException("Combined length of values is too long (> Integer.MAX_VALUE)");
    }

    MutableBytes result = MutableBytes.create(size);
    int offset = 0;
    for (Bytes value : values) {
      value.copyTo(result, offset);
      offset += value.size();
    }
    return result;
  }

  /**
   * Wrap a full Vert.x {@link Buffer} as a {@link Bytes} value.
   *
   * <p>
   * Note that any change to the content of the buffer may be reflected in the returned value.
   *
   * @param buffer The buffer to wrap.
   * @return A {@link Bytes} value.
   */
  static Bytes wrapBuffer(Buffer buffer) {
    checkNotNull(buffer);
    if (buffer.length() == 0) {
      return EMPTY;
    }
    return new BufferWrappingBytes(buffer);
  }

  /**
   * Wrap a slice of a Vert.x {@link Buffer} as a {@link Bytes} value.
   *
   * <p>
   * Note that any change to the content of the buffer may be reflected in the returned value.
   *
   * @param buffer The buffer to wrap.
   * @param offset The offset in {@code buffer} from which to expose the bytes in the returned value. That is,
   *        {@code wrapBuffer(buffer, i, 1).get(0) == buffer.getByte(i)}.
   * @param size The size of the returned value.
   * @return A {@link Bytes} value.
   * @throws IndexOutOfBoundsException if {@code offset &lt; 0 || (buffer.length() > 0 && offset >=
   *     buffer.length())}.
   * @throws IllegalArgumentException if {@code length &lt; 0 || offset + length > buffer.length()}.
   */
  static Bytes wrapBuffer(Buffer buffer, int offset, int size) {
    checkNotNull(buffer);
    if (size == 0) {
      return EMPTY;
    }
    return new BufferWrappingBytes(buffer, offset, size);
  }

  /**
   * Wrap a full Netty {@link ByteBuf} as a {@link Bytes} value.
   *
   * <p>
   * Note that any change to the content of the byteBuf may be reflected in the returned value.
   *
   * @param byteBuf The {@link ByteBuf} to wrap.
   * @return A {@link Bytes} value.
   */
  static Bytes wrapByteBuf(ByteBuf byteBuf) {
    checkNotNull(byteBuf);
    if (byteBuf.capacity() == 0) {
      return EMPTY;
    }
    return new ByteBufWrappingBytes(byteBuf);
  }

  /**
   * Wrap a slice of a Netty {@link ByteBuf} as a {@link Bytes} value.
   *
   * <p>
   * Note that any change to the content of the buffer may be reflected in the returned value.
   *
   * @param byteBuf The {@link ByteBuf} to wrap.
   * @param offset The offset in {@code byteBuf} from which to expose the bytes in the returned value. That is,
   *        {@code wrapByteBuf(byteBuf, i, 1).get(0) == byteBuf.getByte(i)}.
   * @param size The size of the returned value.
   * @return A {@link Bytes} value.
   * @throws IndexOutOfBoundsException if {@code offset &lt; 0 || (byteBuf.capacity() > 0 && offset >=
   *     byteBuf.capacity())}.
   * @throws IllegalArgumentException if {@code length &lt; 0 || offset + length > byteBuf.capacity()}.
   */
  static Bytes wrapByteBuf(ByteBuf byteBuf, int offset, int size) {
    checkNotNull(byteBuf);
    if (size == 0) {
      return EMPTY;
    }
    return new ByteBufWrappingBytes(byteBuf, offset, size);
  }

  /**
   * Wrap a full Java NIO {@link ByteBuffer} as a {@link Bytes} value.
   *
   * <p>
   * Note that any change to the content of the byteBuf may be reflected in the returned value.
   *
   * @param byteBuffer The {@link ByteBuffer} to wrap.
   * @return A {@link Bytes} value.
   */
  static Bytes wrapByteBuffer(ByteBuffer byteBuffer) {
    checkNotNull(byteBuffer);
    if (byteBuffer.limit() == 0) {
      return EMPTY;
    }
    return new ByteBufferWrappingBytes(byteBuffer);
  }

  /**
   * Wrap a slice of a Java NIO {@link ByteBuf} as a {@link Bytes} value.
   *
   * <p>
   * Note that any change to the content of the buffer may be reflected in the returned value.
   *
   * @param byteBuffer The {@link ByteBuffer} to wrap.
   * @param offset The offset in {@code byteBuffer} from which to expose the bytes in the returned value. That is,
   *        {@code wrapByteBuffer(byteBuffer, i, 1).get(0) == byteBuffer.getByte(i)}.
   * @param size The size of the returned value.
   * @return A {@link Bytes} value.
   * @throws IndexOutOfBoundsException if {@code offset &lt; 0 || (byteBuffer.limit() > 0 && offset >=
   *     byteBuf.limit())}.
   * @throws IllegalArgumentException if {@code length &lt; 0 || offset + length > byteBuffer.limit()}.
   */
  static Bytes wrapByteBuffer(ByteBuffer byteBuffer, int offset, int size) {
    checkNotNull(byteBuffer);
    if (size == 0) {
      return EMPTY;
    }
    return new ByteBufferWrappingBytes(byteBuffer, offset, size);
  }

  /**
   * Create a value that contains the specified bytes in their specified order.
   *
   * @param bytes The bytes that must compose the returned value.
   * @return A value containing the specified bytes.
   */
  static Bytes of(byte... bytes) {
    return wrap(bytes);
  }

  /**
   * Create a value that contains the specified bytes in their specified order.
   *
   * @param bytes The bytes.
   * @return A value containing bytes are the one from {@code bytes}.
   * @throws IllegalArgumentException if any of the specified would be truncated when storing as a byte.
   */
  static Bytes of(int... bytes) {
    byte[] result = new byte[bytes.length];
    for (int i = 0; i < bytes.length; i++) {
      int b = bytes[i];
      checkArgument(b == (((byte) b) & 0xff), "%sth value %s does not fit a byte", i + 1, b);
      result[i] = (byte) b;
    }
    return Bytes.wrap(result);
  }

  /**
   * Return a 2-byte value corresponding to the provided value interpreted as an unsigned short.
   *
   * @param value The value, which must be no larger than an unsigned short.
   * @return A 2 bytes value corresponding to {@code value}.
   * @throws IllegalArgumentException if {@code value < 0} or {@code value} is too big to fit an unsigned 2-byte short
   *         (that is, if {@code value >= (1 << 16)}).
   */
  static Bytes ofUnsignedShort(int value) {
    return ofUnsignedShort(value, BIG_ENDIAN);
  }

  /**
   * Return a 2-byte value corresponding to the provided value interpreted as an unsigned short.
   *
   * @param value The value, which must be no larger than an unsigned short.
   * @param order The byte-order for the integer encoding.
   * @return A 2 bytes value corresponding to {@code value}.
   * @throws IllegalArgumentException if {@code value < 0} or {@code value} is too big to fit an unsigned 2-byte short
   *         (that is, if {@code value >= (1 << 16)}).
   */
  static Bytes ofUnsignedShort(int value, ByteOrder order) {
    checkArgument(
        value >= 0 && value <= BytesValues.MAX_UNSIGNED_SHORT,
        "Value %s cannot be represented as an unsigned short (it is negative or too big)",
        value);
    byte[] res = new byte[2];
    if (order == BIG_ENDIAN) {
      res[0] = (byte) ((value >> 8) & 0xFF);
      res[1] = (byte) (value & 0xFF);
    } else {
      res[0] = (byte) (value & 0xFF);
      res[1] = (byte) ((value >> 8) & 0xFF);
    }
    return Bytes.wrap(res);
  }

  /**
   * Return a 4-byte value corresponding to the provided value interpreted as an unsigned int.
   *
   * @param value The value, which must be no larger than an unsigned int.
   * @return A 4 bytes value corresponding to {@code value}.
   * @throws IllegalArgumentException if {@code value < 0} or {@code value} is too big to fit an unsigned 4-byte int
   *         (that is, if {@code value >= (1L << 32)}).
   */
  static Bytes ofUnsignedInt(long value) {
    return ofUnsignedInt(value, BIG_ENDIAN);
  }

  /**
   * Return a 4-byte value corresponding to the provided value interpreted as an unsigned int.
   *
   * @param value The value, which must be no larger than an unsigned int.
   * @param order The byte-order for the integer encoding.
   * @return A 4 bytes value corresponding to the encoded {@code value}.
   * @throws IllegalArgumentException if {@code value < 0} or {@code value} is too big to fit an unsigned 4-byte int
   *         (that is, if {@code value >= (1L << 32)}).
   */
  static Bytes ofUnsignedInt(long value, ByteOrder order) {
    checkArgument(
        value >= 0 && value <= BytesValues.MAX_UNSIGNED_INT,
        "Value %s cannot be represented as an unsigned int (it is negative or too big)",
        value);
    byte[] res = new byte[4];
    if (order == BIG_ENDIAN) {
      res[0] = (byte) ((value >> 24) & 0xFF);
      res[1] = (byte) ((value >> 16) & 0xFF);
      res[2] = (byte) ((value >> 8) & 0xFF);
      res[3] = (byte) ((value) & 0xFF);
    } else {
      res[0] = (byte) ((value) & 0xFF);
      res[1] = (byte) ((value >> 8) & 0xFF);
      res[2] = (byte) ((value >> 16) & 0xFF);
      res[3] = (byte) ((value >> 24) & 0xFF);
    }
    return Bytes.wrap(res);
  }

  /**
   * Return an 8-byte value corresponding to the provided value interpreted as an unsigned long.
   *
   * @param value The value, which will be interpreted as an unsigned long.
   * @return A 8 bytes value corresponding to {@code value}.
   * @throws IllegalArgumentException if {@code value < 0} or {@code value} is too big to fit an unsigned 8-byte int
   *         (that is, if {@code value >= (1L << 64)}).
   */
  static Bytes ofUnsignedLong(long value) {
    return ofUnsignedLong(value, BIG_ENDIAN);
  }

  /**
   * Return an 8-byte value corresponding to the provided value interpreted as an unsigned long.
   *
   * @param value The value, which will be interpreted as an unsigned long.
   * @param order The byte-order for the integer encoding.
   * @return A 8 bytes value corresponding to {@code value}.
   * @throws IllegalArgumentException if {@code value < 0} or {@code value} is too big to fit an unsigned 8-byte int
   *         (that is, if {@code value >= (1L << 64)}).
   */
  static Bytes ofUnsignedLong(long value, ByteOrder order) {
    byte[] res = new byte[8];
    if (order == BIG_ENDIAN) {
      res[0] = (byte) ((value >> 56) & 0xFF);
      res[1] = (byte) ((value >> 48) & 0xFF);
      res[2] = (byte) ((value >> 40) & 0xFF);
      res[3] = (byte) ((value >> 32) & 0xFF);
      res[4] = (byte) ((value >> 24) & 0xFF);
      res[5] = (byte) ((value >> 16) & 0xFF);
      res[6] = (byte) ((value >> 8) & 0xFF);
      res[7] = (byte) (value & 0xFF);
    } else {
      res[0] = (byte) ((value) & 0xFF);
      res[1] = (byte) ((value >> 8) & 0xFF);
      res[2] = (byte) ((value >> 16) & 0xFF);
      res[3] = (byte) ((value >> 24) & 0xFF);
      res[4] = (byte) ((value >> 32) & 0xFF);
      res[5] = (byte) ((value >> 40) & 0xFF);
      res[6] = (byte) ((value >> 48) & 0xFF);
      res[7] = (byte) ((value >> 56) & 0xFF);
    }
    return Bytes.wrap(res);
  }

  /**
   * Return the smallest bytes value whose bytes correspond to the provided long. That is, the returned value may be of
   * size less than 8 if the provided long has leading zero bytes.
   *
   * @param value The long from which to create the bytes value.
   * @return The minimal bytes representation corresponding to {@code l}.
   */
  static Bytes minimalBytes(long value) {
    if (value == 0) {
      return Bytes.EMPTY;
    }

    int zeros = Long.numberOfLeadingZeros(value);
    int resultBytes = 8 - (zeros / 8);

    byte[] result = new byte[resultBytes];
    int shift = 0;
    for (int i = 0; i < resultBytes; i++) {
      result[resultBytes - i - 1] = (byte) ((value >> shift) & 0xFF);
      shift += 8;
    }
    return Bytes.wrap(result);
  }

  /**
   * Parse a hexadecimal string into a {@link Bytes} value.
   *
   * <p>
   * This method is lenient in that {@code str} may of an odd length, in which case it will behave exactly as if it had
   * an additional 0 in front.
   *
   * @param str The hexadecimal string to parse, which may or may not start with "0x".
   * @return The value corresponding to {@code str}.
   * @throws IllegalArgumentException if {@code str} does not correspond to a valid hexadecimal representation.
   */
  static Bytes fromHexStringLenient(CharSequence str) {
    checkNotNull(str);
    return BytesValues.fromHexString(str, -1, true);
  }

  /**
   * Parse a hexadecimal string into a {@link Bytes} value of the provided size.
   *
   * <p>
   * This method allows for {@code str} to have an odd length, in which case it will behave exactly as if it had an
   * additional 0 in front.
   *
   * @param str The hexadecimal string to parse, which may or may not start with "0x".
   * @param destinationSize The size of the returned value, which must be big enough to hold the bytes represented by
   *        {@code str}. If it is strictly bigger those bytes from {@code str}, the returned value will be left padded
   *        with zeros.
   * @return A value of size {@code destinationSize} corresponding to {@code str} potentially left-padded.
   * @throws IllegalArgumentException if {@code str} does not correspond to a valid hexadecimal representation,
   *         represents more bytes than {@code destinationSize} or {@code destinationSize &lt; 0}.
   */
  static Bytes fromHexStringLenient(CharSequence str, int destinationSize) {
    checkNotNull(str);
    checkArgument(destinationSize >= 0, "Invalid negative destination size %s", destinationSize);
    return BytesValues.fromHexString(str, destinationSize, true);
  }

  /**
   * Parse a hexadecimal string into a {@link Bytes} value.
   *
   * <p>
   * This method requires that {@code str} have an even length.
   *
   * @param str The hexadecimal string to parse, which may or may not start with "0x".
   * @return The value corresponding to {@code str}.
   * @throws IllegalArgumentException if {@code str} does not correspond to a valid hexadecimal representation, or is of
   *         an odd length.
   */
  static Bytes fromHexString(CharSequence str) {
    checkNotNull(str);
    return BytesValues.fromHexString(str, -1, false);
  }

  /**
   * Parse a hexadecimal string into a {@link Bytes} value.
   *
   * <p>
   * This method requires that {@code str} have an even length.
   *
   * @param str The hexadecimal string to parse, which may or may not start with "0x".
   * @param destinationSize The size of the returned value, which must be big enough to hold the bytes represented by
   *        {@code str}. If it is strictly bigger those bytes from {@code str}, the returned value will be left padded
   *        with zeros.
   * @return A value of size {@code destinationSize} corresponding to {@code str} potentially left-padded.
   * @throws IllegalArgumentException if {@code str} does correspond to a valid hexadecimal representation, or is of an
   *         odd length.
   * @throws IllegalArgumentException if {@code str} does not correspond to a valid hexadecimal representation, or is of
   *         an odd length, or represents more bytes than {@code destinationSize} or {@code destinationSize &lt; 0}.
   */
  static Bytes fromHexString(CharSequence str, int destinationSize) {
    checkNotNull(str);
    checkArgument(destinationSize >= 0, "Invalid negative destination size %s", destinationSize);
    return BytesValues.fromHexString(str, destinationSize, false);
  }

  /**
   * Parse a base 64 string into a {@link Bytes} value.
   *
   * @param str The base 64 string to parse.
   * @return The value corresponding to {@code str}.
   */
  static Bytes fromBase64String(CharSequence str) {
    return Bytes.wrap(Base64.getDecoder().decode(str.toString()));
  }

  /**
   * Generate random bytes.
   *
   * @param size The number of bytes to generate.
   * @return A value containing the desired number of random bytes.
   */
  static Bytes random(int size) {
    return random(size, new SecureRandom());
  }

  /**
   * Generate random bytes.
   *
   * @param size The number of bytes to generate.
   * @param generator The generator for random bytes.
   * @return A value containing the desired number of random bytes.
   */
  static Bytes random(int size, Random generator) {
    byte[] array = new byte[size];
    generator.nextBytes(array);
    return Bytes.wrap(array);
  }

  /** @return The number of bytes this value represents. */
  int size();

  /**
   * Retrieve a byte in this value.
   *
   * @param i The index of the byte to fetch within the value (0-indexed).
   * @return The byte at index {@code i} in this value.
   * @throws IndexOutOfBoundsException if {@code i &lt; 0} or {i &gt;= size()}.
   */
  byte get(int i);

  /**
   * Retrieve the 4 bytes starting at the provided index in this value as an integer.
   *
   * @param i The index from which to get the int, which must less than or equal to {@code size() - 4}.
   * @return An integer whose value is the 4 bytes from this value starting at index {@code i}.
   * @throws IndexOutOfBoundsException if {@code i &lt; 0} or {@code i &gt; size() - 4}.
   */
  default int getInt(int i) {
    return getInt(i, BIG_ENDIAN);
  }

  /**
   * Retrieve the 4 bytes starting at the provided index in this value as an integer.
   *
   * @param i The index from which to get the int, which must less than or equal to {@code size() - 4}.
   * @param order The byte-order for decoding the integer.
   * @return An integer whose value is the 4 bytes from this value starting at index {@code i}.
   * @throws IndexOutOfBoundsException if {@code i &lt; 0} or {@code i &gt; size() - 4}.
   */
  default int getInt(int i, ByteOrder order) {
    int size = size();
    checkElementIndex(i, size);
    if (i > (size - 4)) {
      throw new IndexOutOfBoundsException(
          format("Value of size %s has not enough bytes to read a 4 bytes int from index %s", size, i));
    }

    int value = 0;
    if (order == BIG_ENDIAN) {
      value |= ((int) get(i) & 0xFF) << 24;
      value |= ((int) get(i + 1) & 0xFF) << 16;
      value |= ((int) get(i + 2) & 0xFF) << 8;
      value |= ((int) get(i + 3) & 0xFF);
    } else {
      value |= ((int) get(i + 3) & 0xFF) << 24;
      value |= ((int) get(i + 2) & 0xFF) << 16;
      value |= ((int) get(i + 1) & 0xFF) << 8;
      value |= ((int) get(i) & 0xFF);
    }
    return value;
  }

  /**
   * The value corresponding to interpreting these bytes as an integer.
   *
   * @return An value corresponding to this value interpreted as an integer.
   * @throws IllegalArgumentException if {@code size() &gt; 4}.
   */
  default int toInt() {
    return toInt(BIG_ENDIAN);
  }

  /**
   * The value corresponding to interpreting these bytes as an integer.
   *
   * @param order The byte-order for decoding the integer.
   * @return An value corresponding to this value interpreted as an integer.
   * @throws IllegalArgumentException if {@code size() &gt; 4}.
   */
  default int toInt(ByteOrder order) {
    int size = size();
    checkArgument(size <= 4, "Value of size %s has more than 4 bytes", size());
    if (size == 0) {
      return 0;
    }
    if (order == BIG_ENDIAN) {
      int i = size;
      int value = ((int) get(--i) & 0xFF);
      if (i == 0) {
        return value;
      }
      value |= ((int) get(--i) & 0xFF) << 8;
      if (i == 0) {
        return value;
      }
      value |= ((int) get(--i) & 0xFF) << 16;
      if (i == 0) {
        return value;
      }
      return value | ((int) get(--i) & 0xFF) << 24;
    } else {
      int i = 0;
      int value = ((int) get(i) & 0xFF);
      if (++i == size) {
        return value;
      }
      value |= ((int) get(i++) & 0xFF) << 8;
      if (i == size) {
        return value;
      }
      value |= ((int) get(i++) & 0xFF) << 16;
      if (i == size) {
        return value;
      }
      return value | ((int) get(i) & 0xFF) << 24;
    }
  }

  /**
   * Whether this value contains no bytes.
   *
   * @return true if the value contains no bytes
   */
  default boolean isEmpty() {
    return size() == 0;
  }

  /**
   * Retrieves the 8 bytes starting at the provided index in this value as a long.
   *
   * @param i The index from which to get the long, which must less than or equal to {@code size() - 8}.
   * @return A long whose value is the 8 bytes from this value starting at index {@code i}.
   * @throws IndexOutOfBoundsException if {@code i &lt; 0} or {@code i &gt; size() - 8}.
   */
  default long getLong(int i) {
    return getLong(i, BIG_ENDIAN);
  }

  /**
   * Retrieves the 8 bytes starting at the provided index in this value as a long.
   *
   * @param i The index from which to get the long, which must less than or equal to {@code size() - 8}.
   * @param order The byte-order for decoding the integer.
   * @return A long whose value is the 8 bytes from this value starting at index {@code i}.
   * @throws IndexOutOfBoundsException if {@code i &lt; 0} or {@code i &gt; size() - 8}.
   */
  default long getLong(int i, ByteOrder order) {
    int size = size();
    checkElementIndex(i, size);
    if (i > (size - 8)) {
      throw new IndexOutOfBoundsException(
          format("Value of size %s has not enough bytes to read a 8 bytes long from index %s", size, i));
    }

    long value = 0;
    if (order == BIG_ENDIAN) {
      value |= ((long) get(i) & 0xFF) << 56;
      value |= ((long) get(i + 1) & 0xFF) << 48;
      value |= ((long) get(i + 2) & 0xFF) << 40;
      value |= ((long) get(i + 3) & 0xFF) << 32;
      value |= ((long) get(i + 4) & 0xFF) << 24;
      value |= ((long) get(i + 5) & 0xFF) << 16;
      value |= ((long) get(i + 6) & 0xFF) << 8;
      value |= ((long) get(i + 7) & 0xFF);
    } else {
      value |= ((long) get(i + 7) & 0xFF) << 56;
      value |= ((long) get(i + 6) & 0xFF) << 48;
      value |= ((long) get(i + 5) & 0xFF) << 40;
      value |= ((long) get(i + 4) & 0xFF) << 32;
      value |= ((long) get(i + 3) & 0xFF) << 24;
      value |= ((long) get(i + 2) & 0xFF) << 16;
      value |= ((long) get(i + 1) & 0xFF) << 8;
      value |= ((long) get(i) & 0xFF);
    }
    return value;
  }

  /**
   * The value corresponding to interpreting these bytes as a long.
   *
   * @return An value corresponding to this value interpreted as a long.
   * @throws IllegalArgumentException if {@code size() &gt; 8}.
   */
  default long toLong() {
    return toLong(BIG_ENDIAN);
  }

  /**
   * The value corresponding to interpreting these bytes as a long.
   *
   * @param order The byte-order for decoding the integer.
   * @return An value corresponding to this value interpreted as a long.
   * @throws IllegalArgumentException if {@code size() &gt; 8}.
   */
  default long toLong(ByteOrder order) {
    int size = size();
    checkArgument(size <= 8, "Value of size %s has more than 8 bytes", size());
    if (size == 0) {
      return 0;
    }
    if (order == BIG_ENDIAN) {
      int i = size;
      long value = ((long) get(--i) & 0xFF);
      if (i == 0) {
        return value;
      }
      value |= ((long) get(--i) & 0xFF) << 8;
      if (i == 0) {
        return value;
      }
      value |= ((long) get(--i) & 0xFF) << 16;
      if (i == 0) {
        return value;
      }
      value |= ((long) get(--i) & 0xFF) << 24;
      if (i == 0) {
        return value;
      }
      value |= ((long) get(--i) & 0xFF) << 32;
      if (i == 0) {
        return value;
      }
      value |= ((long) get(--i) & 0xFF) << 40;
      if (i == 0) {
        return value;
      }
      value |= ((long) get(--i) & 0xFF) << 48;
      if (i == 0) {
        return value;
      }
      return value | ((long) get(--i) & 0xFF) << 56;
    } else {
      int i = 0;
      long value = ((long) get(i) & 0xFF);
      if (++i == size) {
        return value;
      }
      value |= ((long) get(i) & 0xFF) << 8;
      if (++i == size) {
        return value;
      }
      value |= ((long) get(i) & 0xFF) << 16;
      if (++i == size) {
        return value;
      }
      value |= ((long) get(i) & 0xFF) << 24;
      if (++i == size) {
        return value;
      }
      value |= ((long) get(i) & 0xFF) << 32;
      if (++i == size) {
        return value;
      }
      value |= ((long) get(i) & 0xFF) << 40;
      if (++i == size) {
        return value;
      }
      value |= ((long) get(i) & 0xFF) << 48;
      if (++i == size) {
        return value;
      }
      return value | ((long) get(i) & 0xFF) << 56;
    }
  }

  /**
   * The BigInteger corresponding to interpreting these bytes as a two's-complement signed integer.
   *
   * @return A {@link BigInteger} corresponding to interpreting these bytes as a two's-complement signed integer.
   */
  default BigInteger toBigInteger() {
    return toBigInteger(BIG_ENDIAN);
  }

  /**
   * The BigInteger corresponding to interpreting these bytes as a two's-complement signed integer.
   *
   * @param order The byte-order for decoding the integer.
   * @return A {@link BigInteger} corresponding to interpreting these bytes as a two's-complement signed integer.
   */
  default BigInteger toBigInteger(ByteOrder order) {
    if (size() == 0) {
      return BigInteger.ZERO;
    }
    return new BigInteger((order == BIG_ENDIAN) ? toArrayUnsafe() : reverse().toArrayUnsafe());
  }

  /**
   * The BigInteger corresponding to interpreting these bytes as an unsigned integer.
   *
   * @return A positive (or zero) {@link BigInteger} corresponding to interpreting these bytes as an unsigned integer.
   */
  default BigInteger toUnsignedBigInteger() {
    return toUnsignedBigInteger(BIG_ENDIAN);
  }

  /**
   * The BigInteger corresponding to interpreting these bytes as an unsigned integer.
   *
   * @param order The byte-order for decoding the integer.
   * @return A positive (or zero) {@link BigInteger} corresponding to interpreting these bytes as an unsigned integer.
   */
  default BigInteger toUnsignedBigInteger(ByteOrder order) {
    return new BigInteger(1, (order == BIG_ENDIAN) ? toArrayUnsafe() : reverse().toArrayUnsafe());
  }

  /**
   * Whether this value has only zero bytes.
   *
   * @return {@code true} if all the bits of this value are zeros.
   */
  default boolean isZero() {
    for (int i = size() - 1; i >= 0; --i) {
      if (get(i) != 0)
        return false;
    }
    return true;
  }

  /**
   * Whether the bytes start with a zero bit value.
   *
   * @return true if the first bit equals zero
   */
  default boolean hasLeadingZero() {
    return size() > 0 && (get(0) & 0x80) == 0;
  }

  /**
   * @return The number of zero bits preceding the highest-order ("leftmost") one-bit, or {@code size() * 8} if all bits
   *         are zero.
   */
  default int numberOfLeadingZeros() {
    int size = size();
    for (int i = 0; i < size; i++) {
      byte b = get(i);
      if (b == 0) {
        continue;
      }

      return (i * 8) + Integer.numberOfLeadingZeros(b & 0xFF) - 3 * 8;
    }
    return size * 8;
  }

  /**
   * Whether the bytes start with a zero byte value.
   *
   * @return true if the first byte equals zero
   */
  default boolean hasLeadingZeroByte() {
    return size() > 0 && get(0) == 0;
  }

  /**
   * @return The number of leading zero bytes of the value.
   */
  default int numberOfLeadingZeroBytes() {
    int size = size();
    for (int i = 0; i < size; i++) {
      if (get(i) != 0) {
        return i;
      }
    }
    return size;
  }

  /**
   * @return The number of trailing zero bytes of the value.
   */
  default int numberOfTrailingZeroBytes() {
    int size = size();
    for (int i = size; i >= 1; i--) {
      if (get(i - 1) != 0) {
        return size - i;
      }
    }
    return size;
  }

  /**
   * @return The number of bits following and including the highest-order ("leftmost") one-bit, or zero if all bits are
   *         zero.
   */
  default int bitLength() {
    int size = size();
    for (int i = 0; i < size; i++) {
      byte b = get(i);
      if (b == 0)
        continue;

      return (size * 8) - (i * 8) - (Integer.numberOfLeadingZeros(b & 0xFF) - 3 * 8);
    }
    return 0;
  }

  /**
   * Return a bit-wise AND of these bytes and the supplied bytes.
   *
   * If this value and the supplied value are different lengths, then the shorter will be zero-padded to the left.
   *
   * @param other The bytes to perform the operation with.
   * @return The result of a bit-wise AND.
   */
  default Bytes and(Bytes other) {
    return and(other, MutableBytes.create(Math.max(size(), other.size())));
  }

  /**
   * Calculate a bit-wise AND of these bytes and the supplied bytes.
   *
   * <p>
   * If this value or the supplied value are shorter in length than the output vector, then they will be zero-padded to
   * the left. Likewise, if either this value or the supplied valid is longer in length than the output vector, then
   * they will be truncated to the left.
   *
   * @param other The bytes to perform the operation with.
   * @param result The mutable output vector for the result.
   * @param <T> The {@link MutableBytes} value type.
   * @return The {@code result} output vector.
   */
  default <T extends MutableBytes> T and(Bytes other, T result) {
    checkNotNull(other);
    checkNotNull(result);
    int rSize = result.size();
    int offsetSelf = rSize - size();
    int offsetOther = rSize - other.size();
    for (int i = 0; i < rSize; i++) {
      byte b1 = (i < offsetSelf) ? 0x00 : get(i - offsetSelf);
      byte b2 = (i < offsetOther) ? 0x00 : other.get(i - offsetOther);
      result.set(i, (byte) (b1 & b2));
    }
    return result;
  }

  /**
   * Return a bit-wise OR of these bytes and the supplied bytes.
   *
   * <p>
   * If this value and the supplied value are different lengths, then the shorter will be zero-padded to the left.
   *
   * @param other The bytes to perform the operation with.
   * @return The result of a bit-wise OR.
   */
  default Bytes or(Bytes other) {
    return or(other, MutableBytes.create(Math.max(size(), other.size())));
  }

  /**
   * Calculate a bit-wise OR of these bytes and the supplied bytes.
   *
   * <p>
   * If this value or the supplied value are shorter in length than the output vector, then they will be zero-padded to
   * the left. Likewise, if either this value or the supplied valid is longer in length than the output vector, then
   * they will be truncated to the left.
   *
   * @param other The bytes to perform the operation with.
   * @param result The mutable output vector for the result.
   * @param <T> The {@link MutableBytes} value type.
   * @return The {@code result} output vector.
   */
  default <T extends MutableBytes> T or(Bytes other, T result) {
    checkNotNull(other);
    checkNotNull(result);
    int rSize = result.size();
    int offsetSelf = rSize - size();
    int offsetOther = rSize - other.size();
    for (int i = 0; i < rSize; i++) {
      byte b1 = (i < offsetSelf) ? 0x00 : get(i - offsetSelf);
      byte b2 = (i < offsetOther) ? 0x00 : other.get(i - offsetOther);
      result.set(i, (byte) (b1 | b2));
    }
    return result;
  }

  /**
   * Return a bit-wise XOR of these bytes and the supplied bytes.
   *
   * <p>
   * If this value and the supplied value are different lengths, then the shorter will be zero-padded to the left.
   *
   * @param other The bytes to perform the operation with.
   * @return The result of a bit-wise XOR.
   */
  default Bytes xor(Bytes other) {
    return xor(other, MutableBytes.create(Math.max(size(), other.size())));
  }

  /**
   * Calculate a bit-wise XOR of these bytes and the supplied bytes.
   *
   * <p>
   * If this value or the supplied value are shorter in length than the output vector, then they will be zero-padded to
   * the left. Likewise, if either this value or the supplied valid is longer in length than the output vector, then
   * they will be truncated to the left.
   *
   * @param other The bytes to perform the operation with.
   * @param result The mutable output vector for the result.
   * @param <T> The {@link MutableBytes} value type.
   * @return The {@code result} output vector.
   */
  default <T extends MutableBytes> T xor(Bytes other, T result) {
    checkNotNull(other);
    checkNotNull(result);
    int rSize = result.size();
    int offsetSelf = rSize - size();
    int offsetOther = rSize - other.size();
    for (int i = 0; i < rSize; i++) {
      byte b1 = (i < offsetSelf) ? 0x00 : get(i - offsetSelf);
      byte b2 = (i < offsetOther) ? 0x00 : other.get(i - offsetOther);
      result.set(i, (byte) (b1 ^ b2));
    }
    return result;
  }

  /**
   * Return a bit-wise NOT of these bytes.
   *
   * @return The result of a bit-wise NOT.
   */
  default Bytes not() {
    return not(MutableBytes.create(size()));
  }

  /**
   * Calculate a bit-wise NOT of these bytes.
   *
   * <p>
   * If this value is shorter in length than the output vector, then it will be zero-padded to the left. Likewise, if
   * this value is longer in length than the output vector, then it will be truncated to the left.
   *
   * @param result The mutable output vector for the result.
   * @param <T> The {@link MutableBytes} value type.
   * @return The {@code result} output vector.
   */
  default <T extends MutableBytes> T not(T result) {
    checkNotNull(result);
    int rSize = result.size();
    int offsetSelf = rSize - size();
    for (int i = 0; i < rSize; i++) {
      byte b1 = (i < offsetSelf) ? 0x00 : get(i - offsetSelf);
      result.set(i, (byte) ~b1);
    }
    return result;
  }

  /**
   * Shift all bits in this value to the right.
   *
   * @param distance The number of bits to shift by.
   * @return A value containing the shifted bits.
   */
  default Bytes shiftRight(int distance) {
    return shiftRight(distance, MutableBytes.create(size()));
  }

  /**
   * Shift all bits in this value to the right.
   *
   * <p>
   * If this value is shorter in length than the output vector, then it will be zero-padded to the left. Likewise, if
   * this value is longer in length than the output vector, then it will be truncated to the left (after shifting).
   *
   * @param distance The number of bits to shift by.
   * @param result The mutable output vector for the result.
   * @param <T> The {@link MutableBytes} value type.
   * @return The {@code result} output vector.
   */
  default <T extends MutableBytes> T shiftRight(int distance, T result) {
    checkNotNull(result);
    int rSize = result.size();
    int offsetSelf = rSize - size();

    int d = distance / 8;
    int s = distance % 8;
    int resIdx = rSize - 1;
    for (int i = rSize - 1 - d; i >= 0; i--) {
      byte res;
      if (i < offsetSelf) {
        res = 0;
      } else {
        int selfIdx = i - offsetSelf;
        int leftSide = (get(selfIdx) & 0xFF) >>> s;
        int rightSide = (selfIdx == 0) ? 0 : get(selfIdx - 1) << (8 - s);
        res = (byte) (leftSide | rightSide);
      }
      result.set(resIdx--, res);
    }
    for (; resIdx >= 0; resIdx--) {
      result.set(resIdx, (byte) 0);
    }
    return result;
  }

  /**
   * Shift all bits in this value to the left.
   *
   * @param distance The number of bits to shift by.
   * @return A value containing the shifted bits.
   */
  default Bytes shiftLeft(int distance) {
    return shiftLeft(distance, MutableBytes.create(size()));
  }

  /**
   * Shift all bits in this value to the left.
   *
   * <p>
   * If this value is shorter in length than the output vector, then it will be zero-padded to the left. Likewise, if
   * this value is longer in length than the output vector, then it will be truncated to the left.
   *
   * @param distance The number of bits to shift by.
   * @param result The mutable output vector for the result.
   * @param <T> The {@link MutableBytes} value type.
   * @return The {@code result} output vector.
   */
  default <T extends MutableBytes> T shiftLeft(int distance, T result) {
    checkNotNull(result);
    int size = size();
    int rSize = result.size();
    int offsetSelf = rSize - size;

    int d = distance / 8;
    int s = distance % 8;
    int resIdx = 0;
    for (int i = d; i < rSize; i++) {
      byte res;
      if (i < offsetSelf) {
        res = 0;
      } else {
        int selfIdx = i - offsetSelf;
        int leftSide = get(selfIdx) << s;
        int rightSide = (selfIdx == size - 1) ? 0 : (get(selfIdx + 1) & 0xFF) >>> (8 - s);
        res = (byte) (leftSide | rightSide);
      }
      result.set(resIdx++, res);
    }
    for (; resIdx < rSize; resIdx++) {
      result.set(resIdx, (byte) 0);
    }
    return result;
  }

  /**
   * Create a new value representing (a view of) a slice of the bytes of this value.
   *
   * <p>
   * Please note that the resulting slice is only a view and as such maintains a link to the underlying full value. So
   * holding a reference to the returned slice may hold more memory than the slide represents. Use {@link #copy} on the
   * returned slice if that is not what you want.
   *
   * @param i The start index for the slice.
   * @return A new value providing a view over the bytes from index {@code i} (included) to the end.
   * @throws IndexOutOfBoundsException if {@code i &lt; 0}.
   */
  default Bytes slice(int i) {
    if (i == 0) {
      return this;
    }
    int size = size();
    if (i >= size) {
      return EMPTY;
    }
    return slice(i, size - i);
  }

  /**
   * Create a new value representing (a view of) a slice of the bytes of this value.
   *
   * <p>
   * Please note that the resulting slice is only a view and as such maintains a link to the underlying full value. So
   * holding a reference to the returned slice may hold more memory than the slide represents. Use {@link #copy} on the
   * returned slice if that is not what you want.
   *
   * @param i The start index for the slice.
   * @param length The length of the resulting value.
   * @return A new value providing a view over the bytes from index {@code i} (included) to {@code i + length}
   *         (excluded).
   * @throws IllegalArgumentException if {@code length &lt; 0}.
   * @throws IndexOutOfBoundsException if {@code i &lt; 0} or {i &gt;= size()} or {i + length &gt; size()} .
   */
  Bytes slice(int i, int length);

  /**
   * Return a value equivalent to this one but guaranteed to 1) be deeply immutable (i.e. the underlying value will be
   * immutable) and 2) to not retain more bytes than exposed by the value.
   *
   * @return A value, equals to this one, but deeply immutable and that doesn't retain any "unreachable" bytes. For
   *         performance reasons, this is allowed to return this value however if it already fit those constraints.
   */
  Bytes copy();

  /**
   * Return a new mutable value initialized with the content of this value.
   *
   * @return A mutable copy of this value. This will copy bytes, modifying the returned value will <b>not</b> modify
   *         this value.
   */
  MutableBytes mutableCopy();

  /**
   * Copy the bytes of this value to the provided mutable one, which must have the same size.
   *
   * @param destination The mutable value to which to copy the bytes to, which must have the same size as this value. If
   *        you want to copy value where size differs, you should use {@link #slice} and/or
   *        {@link MutableBytes#mutableSlice} and apply the copy to the result.
   * @throws IllegalArgumentException if {@code this.size() != destination.size()}.
   */
  default void copyTo(MutableBytes destination) {
    checkNotNull(destination);
    checkArgument(
        destination.size() == size(),
        "Cannot copy %s bytes to destination of non-equal size %s",
        size(),
        destination.size());
    copyTo(destination, 0);
  }

  /**
   * Copy the bytes of this value to the provided mutable one from a particular offset.
   *
   * <p>
   * This is a (potentially slightly more efficient) shortcut for {@code
   * copyTo(destination.mutableSlice(destinationOffset, this.size()))}.
   *
   * @param destination The mutable value to which to copy the bytes to, which must have enough bytes from
   *        {@code destinationOffset} for the copied value.
   * @param destinationOffset The offset in {@code destination} at which the copy starts.
   * @throws IllegalArgumentException if the destination doesn't have enough room, that is if {@code
   *     this.size() &gt; (destination.size() - destinationOffset)}.
   */
  default void copyTo(MutableBytes destination, int destinationOffset) {
    checkNotNull(destination);

    // Special casing an empty source or the following checks might throw (even though we have
    // nothing to copy anyway) and this gets inconvenient for generic methods using copyTo() as
    // they may have to special case empty values because of this. As an example,
    // concatenate(EMPTY, EMPTY) would need to be special cased without this.
    int size = size();
    if (size == 0) {
      return;
    }

    checkElementIndex(destinationOffset, destination.size());
    checkArgument(
        destination.size() - destinationOffset >= size,
        "Cannot copy %s bytes, destination has only %s bytes from index %s",
        size,
        destination.size() - destinationOffset,
        destinationOffset);

    for (int i = 0; i < size; i++) {
      destination.set(destinationOffset + i, get(i));
    }
  }

  /**
   * Append the bytes of this value to the {@link ByteBuffer}.
   *
   * @param byteBuffer The {@link ByteBuffer} to which to append this value.
   * @throws BufferOverflowException If the writer attempts to write more than the provided buffer can hold.
   * @throws ReadOnlyBufferException If the provided buffer is read-only.
   */
  default void appendTo(ByteBuffer byteBuffer) {
    checkNotNull(byteBuffer);
    for (int i = 0; i < size(); i++) {
      byteBuffer.put(get(i));
    }
  }

  /**
   * Append the bytes of this value to the provided Vert.x {@link Buffer}.
   *
   * <p>
   * Note that since a Vert.x {@link Buffer} will grow as necessary, this method never fails.
   *
   * @param buffer The {@link Buffer} to which to append this value.
   */
  default void appendTo(Buffer buffer) {
    checkNotNull(buffer);
    for (int i = 0; i < size(); i++) {
      buffer.appendByte(get(i));
    }
  }

  /**
   * Append this value as a sequence of hexadecimal characters.
   *
   * @param appendable The appendable
   * @param <T> The appendable type.
   * @return The appendable.
   * @throws IOException If an IO error occurs.
   */
  default <T extends Appendable> T appendHexTo(T appendable) throws IOException {
    int size = size();
    for (int i = 0; i < size; i++) {
      byte b = get(i);
      appendable.append(AbstractBytes.HEX_CODE[b >> 4 & 15]);
      appendable.append(AbstractBytes.HEX_CODE[b & 15]);
    }
    return appendable;
  }

  /**
   * Return the number of bytes in common between this set of bytes and another.
   *
   * @param other The bytes to compare to.
   * @return The number of common bytes.
   */
  default int commonPrefixLength(Bytes other) {
    checkNotNull(other);
    int ourSize = size();
    int otherSize = other.size();
    int i = 0;
    while (i < ourSize && i < otherSize && get(i) == other.get(i)) {
      i++;
    }
    return i;
  }

  /**
   * Return a slice over the common prefix between this set of bytes and another.
   *
   * @param other The bytes to compare to.
   * @return A slice covering the common prefix.
   */
  default Bytes commonPrefix(Bytes other) {
    return slice(0, commonPrefixLength(other));
  }

  /**
   * Return a slice of representing the same value but without any leading zero bytes.
   *
   * @return {@code value} if its left-most byte is non zero, or a slice that exclude any leading zero bytes.
   */
  default Bytes trimLeadingZeros() {
    int size = size();
    for (int i = 0; i < size; i++) {
      if (get(i) != 0) {
        return slice(i);
      }
    }
    return Bytes.EMPTY;
  }

  /**
   * Update the provided message digest with the bytes of this value.
   *
   * @param digest The digest to update.
   */
  default void update(MessageDigest digest) {
    checkNotNull(digest);
    digest.update(toArrayUnsafe());
  }

  /**
   * Computes the reverse array of bytes of the current bytes.
   *
   * @return a new Bytes value, containing the bytes in reverse order
   */
  default Bytes reverse() {
    byte[] reverse = new byte[size()];
    for (int i = 0; i < size(); i++) {
      reverse[size() - i - 1] = get(i);
    }
    return Bytes.wrap(reverse);
  }

  /**
   * Extract the bytes of this value into a byte array.
   *
   * @return A byte array with the same content than this value.
   */
  default byte[] toArray() {
    int size = size();
    byte[] array = new byte[size];
    for (int i = 0; i < size; i++) {
      array[i] = get(i);
    }
    return array;
  }

  /**
   * Get the bytes represented by this value as byte array.
   *
   * <p>
   * Contrarily to {@link #toArray()}, this may avoid allocating a new array and directly return the backing array of
   * this value if said value is array backed and doing so is possible. As such, modifications to the returned array may
   * or may not impact this value. As such, this method should be used with care and hence the "unsafe" moniker.
   *
   * @return A byte array with the same content than this value, which may or may not be the direct backing of this
   *         value.
   */
  default byte[] toArrayUnsafe() {
    return toArray();
  }

  /**
   * Return the hexadecimal string representation of this value.
   *
   * @return The hexadecimal representation of this value, starting with "0x".
   */
  @Override
  String toString();

  /**
   * @return This value represented as hexadecimal, starting with "0x".
   */
  default String toHexString() {
    try {
      return appendHexTo(new StringBuilder("0x")).toString();
    } catch (IOException e) {
      // not thrown
      throw new RuntimeException(e);
    }
  }

  /**
   * @return This value represented as hexadecimal, with no prefix.
   */
  default String toUnprefixedHexString() {
    try {
      return appendHexTo(new StringBuilder()).toString();
    } catch (IOException e) {
      // not thrown
      throw new RuntimeException(e);
    }
  }

  /** @return This value represented as a minimal hexadecimal string (without any leading zero). */
  default String toShortHexString() {
    StringBuilder hex;
    try {
      hex = appendHexTo(new StringBuilder());
    } catch (IOException e) {
      // not thrown
      throw new RuntimeException(e);
    }

    int i = 0;
    while (i < hex.length() && hex.charAt(i) == '0') {
      i++;
    }
    return "0x" + hex.substring(i);
  }

  /**
   * @return This value represented as base 64.
   */
  default String toBase64String() {
    return Base64.getEncoder().encodeToString(toArrayUnsafe());
  }

  @Override
  default int compareTo(Bytes b) {
    checkNotNull(b);

    int sizeCmp = Integer.compare(bitLength(), b.bitLength());
    if (sizeCmp != 0) {
      return sizeCmp;
    }

    for (int i = 0; i < size(); i++) {
      int cmp = Integer.compare(get(i) & 0xff, b.get(i) & 0xff);
      if (cmp != 0) {
        return cmp;
      }
    }
    return 0;
  }
}
