/*
 * 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 java.lang.String.format;
import static java.nio.ByteOrder.BIG_ENDIAN;
import static org.apache.tuweni.bytes.Checks.checkArgument;
import static org.apache.tuweni.bytes.Checks.checkElementIndex;
import static org.apache.tuweni.bytes.Checks.checkNotNull;

import java.io.IOException;
import java.io.UncheckedIOException;
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.List;
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 < 0 || (value.length > 0 && offset >=
   *     value.length)}.
   * @throws IllegalArgumentException if {@code length < 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 the provided byte array as a {@link Bytes} value, encrypted in memory.
   *
   *
   * @param value The value to secure.
   * @return A {@link Bytes} value securing {@code value}.
   */
  static Bytes secure(byte[] value) {
    return secure(value, 0, value.length);
  }

  /**
   * Wrap a slice of a byte array as a {@link Bytes} value, encrypted in memory.
   *
   *
   * @param value The value to secure.
   * @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 holds securely the bytes of {@code value} from {@code offset} (inclusive) to
   *         {@code offset + length} (exclusive).
   * @throws IndexOutOfBoundsException if {@code offset < 0 || (value.length > 0 && offset >=
   *     value.length)}.
   * @throws IllegalArgumentException if {@code length < 0 || offset + length > value.length}.
   */
  static Bytes secure(byte[] value, int offset, int length) {
    checkNotNull(value);
    return new GuardedByteArrayBytes(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);
  }

  /**
   * 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(List<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(List<Bytes> values) {
    if (values.size() == 0) {
      return EMPTY;
    }

    int size;
    try {
      size = values.stream().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;
  }

  /**
   * 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 < 0 || (buffer.length() > 0 && offset >=
   *     buffer.length())}.
   * @throws IllegalArgumentException if {@code length < 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 < 0 || (byteBuf.capacity() > 0 && offset >=
   *     byteBuf.capacity())}.
   * @throws IllegalArgumentException if {@code length < 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 < 0 || (byteBuffer.limit() > 0 && offset >=
   *     byteBuf.limit())}.
   * @throws IllegalArgumentException if {@code length < 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 < 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 < 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);
  }

  /**
   * Generate a bytes object filled with the same byte.
   *
   * @param b the byte to fill the Bytes with
   * @param size the size of the object
   * @return a value filled with a fixed byte
   */
  static Bytes repeat(byte b, int size) {
    return new ConstantBytesValue(b, size);
  }

  /**
   * Splits a Bytes object into Bytes32 objects. If the last element is not exactly 32 bytes, it is right padded with
   * zeros.
   *
   * @param bytes the bytes object to segment
   * @return an array of Bytes32 objects
   */
  static Bytes32[] segment(Bytes bytes) {
    int segments = (int) Math.ceil(bytes.size() / 32.0);
    Bytes32[] result = new Bytes32[segments];
    for (int i = 0; i < segments; i++) {
      result[i] = Bytes32.rightPad(bytes.slice(i * 32, Math.min(32, bytes.size() - i * 32)));
    }
    return result;
  }

  /**
   *
   * Provides the number of bytes this value represents.
   * 
   * @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 < 0} or {i >= 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 < 0} or {@code i > 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 < 0} or {@code i > 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() > 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() > 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 < 0} or {@code i > 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 < 0} or {@code i > 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() > 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() > 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;
  }

  /**
   * Provides the number of zero bits preceding the highest-order ("leftmost") one-bit, or {@code size() * 8} if all
   * bits * are zero.
   * 
   * @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;
  }

  /**
   * Provides the number of leading zero bytes of the value
   * 
   * @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;
  }

  /**
   * Provides the number of trailing zero bytes of the value.
   * 
   * @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;
  }

  /**
   * Provides the number of bits following and including the highest-order ("leftmost") one-bit, or zero if all bits are
   * zero.
   * 
   * @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 < 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 < 0}.
   * @throws IndexOutOfBoundsException if {@code i < 0} or {i >= size()} or {i + length > 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() > (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);

    destination.set(destinationOffset, this);
  }

  /**
   * 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.
   */
  default <T extends Appendable> T appendHexTo(T appendable) {
    try {
      appendable.append(toFastHex(false));
      return appendable;
    } catch (IOException e) {
      throw new UncheckedIOException(e);
    }
  }

  default String toFastHex(boolean prefix) {

    int offset = prefix ? 2 : 0;

    int resultSize = (size() * 2) + offset;

    char[] result = new char[resultSize];

    if (prefix) {
      result[0] = '0';
      result[1] = 'x';
    }

    for (int i = 0; i < size(); i++) {
      byte b = get(i);
      int pos = i * 2;
      result[pos + offset] = AbstractBytes.HEX_CODE_AS_STRING.charAt(b >> 4 & 15);
      result[pos + offset + 1] = AbstractBytes.HEX_CODE_AS_STRING.charAt(b & 15);
    }

    return new String(result);

  }

  /**
   * 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;
  }

  /**
   * Return a slice of representing the same value but without any trailing zero bytes.
   *
   * @return {@code value} if its right-most byte is non zero, or a slice that exclude any trailing zero bytes.
   */
  default Bytes trimTrailingZeros() {
    int size = size();
    for (int i = size - 1; i >= 0; i--) {
      if (get(i) != 0) {
        return slice(0, i + 1);
      }
    }
    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() {
    return toArray(BIG_ENDIAN);
  }

  /**
   * Extract the bytes of this value into a byte array.
   *
   * @param byteOrder the byte order to apply : big endian or little endian
   * @return A byte array with the same content than this value.
   */
  default byte[] toArray(ByteOrder byteOrder) {
    int size = size();
    byte[] array = new byte[size];
    if (byteOrder == BIG_ENDIAN) {
      for (int i = 0; i < size; i++) {
        array[i] = get(i);
      }
    } else {
      for (int i = 0; i < size(); i++) {
        array[size() - i - 1] = 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();

  /**
   * Provides this value represented as hexadecimal, starting with "0x".
   * 
   * @return This value represented as hexadecimal, starting with "0x".
   */
  default String toHexString() {
    return toFastHex(true);
  }

  /**
   * Provides this value represented as hexadecimal, with no prefix
   * 
   * @return This value represented as hexadecimal, with no prefix.
   */
  default String toUnprefixedHexString() {
    return toFastHex(false);
  }

  default String toEllipsisHexString() {
    int size = size();
    if (size < 6) {
      return toHexString();
    }
    char[] result = new char[12];
    result[0] = '0';
    result[1] = 'x';
    for (int i = 0; i < 2; i++) {
      byte b = get(i);
      int pos = (i * 2) + 2;
      result[pos] = AbstractBytes.HEX_CODE_AS_STRING.charAt(b >> 4 & 15);
      result[pos + 1] = AbstractBytes.HEX_CODE_AS_STRING.charAt(b & 15);
    }
    result[6] = '.';
    result[7] = '.';
    for (int i = 0; i < 2; i++) {
      byte b = get(i + size - 2);
      int pos = (i * 2) + 8;
      result[pos] = AbstractBytes.HEX_CODE_AS_STRING.charAt(b >> 4 & 15);
      result[pos + 1] = AbstractBytes.HEX_CODE_AS_STRING.charAt(b & 15);
    }
    return new String(result);
  }

  /**
   * Provides this value represented as a minimal hexadecimal string (without any leading zero)
   * 
   * @return This value represented as a minimal hexadecimal string (without any leading zero).
   */
  default String toShortHexString() {
    String hex = toFastHex(false);

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

  /**
   * Provides this value represented as a minimal hexadecimal string (without any leading zero, except if it's valued
   * zero or empty, in which case it returns 0x0).
   * 
   * @return This value represented as a minimal hexadecimal string (without any leading zero, except if it's valued
   *         zero or empty, in which case it returns 0x0).
   */
  default String toQuantityHexString() {
    if (Bytes.EMPTY.equals(this)) {
      return "0x0";
    }
    String hex = toFastHex(false);

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

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

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

    int bitLength = bitLength();
    int sizeCmp = Integer.compare(bitLength, b.bitLength());
    if (sizeCmp != 0) {
      return sizeCmp;
    }
    // same bitlength and is zeroes only, return 0.
    if (bitLength == 0) {
      return 0;
    }

    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;
  }
}
