/*
 * 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 org.junit.jupiter.api.Assertions.assertArrayEquals;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertNotEquals;
import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.junit.jupiter.api.Assertions.assertTrue;

import java.math.BigInteger;
import java.nio.ByteBuffer;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import java.util.Arrays;
import java.util.function.Function;

import io.netty.buffer.Unpooled;
import io.vertx.core.buffer.Buffer;
import org.junit.jupiter.api.Test;

abstract class CommonBytesTests {

  abstract Bytes h(String hex);

  abstract MutableBytes m(int size);

  abstract Bytes w(byte[] bytes);

  abstract Bytes of(int... bytes);

  BigInteger bi(String decimal) {
    return new BigInteger(decimal);
  }

  @Test
  void asUnsignedBigInteger() {
    // Make sure things are interpreted unsigned.
    assertEquals(bi("255"), h("0xFF").toUnsignedBigInteger());

    // Try 2^100 + Long.MAX_VALUE, as an easy to define a big not too special big integer.
    BigInteger expected = BigInteger.valueOf(2).pow(100).add(BigInteger.valueOf(Long.MAX_VALUE));

    // 2^100 is a one followed by 100 zeros, that's 12 bytes of zeros (=96) plus 4 more zeros (so
    // 0x10 == 16).
    MutableBytes v = m(13);
    v.set(0, (byte) 16);
    v.setLong(v.size() - 8, Long.MAX_VALUE);
    assertEquals(expected, v.toUnsignedBigInteger());
  }

  @Test
  void testAsSignedBigInteger() {
    // Make sure things are interpreted signed.
    assertEquals(bi("-1"), h("0xFF").toBigInteger());

    // Try 2^100 + Long.MAX_VALUE, as an easy to define a big but not too special big integer.
    BigInteger expected = BigInteger.valueOf(2).pow(100).add(BigInteger.valueOf(Long.MAX_VALUE));

    // 2^100 is a one followed by 100 zeros, that's 12 bytes of zeros (=96) plus 4 more zeros (so
    // 0x10 == 16).
    MutableBytes v = m(13);
    v.set(0, (byte) 16);
    v.setLong(v.size() - 8, Long.MAX_VALUE);
    assertEquals(expected, v.toBigInteger());

    // And for a large negative one, we use -(2^100 + Long.MAX_VALUE), which is:
    //  2^100 + Long.MAX_VALUE = 0x10(4 bytes of 0)7F(  7 bytes of 1)
    //                 inverse = 0xEF(4 bytes of 1)80(  7 bytes of 0)
    //                      +1 = 0xEF(4 bytes of 1)80(6 bytes of 0)01
    expected = expected.negate();
    v = m(13);
    v.set(0, (byte) 0xEF);
    for (int i = 1; i < 5; i++) {
      v.set(i, (byte) 0xFF);
    }
    v.set(5, (byte) 0x80);
    // 6 bytes of 0
    v.set(12, (byte) 1);
    assertEquals(expected, v.toBigInteger());
  }

  @Test
  void testSize() {
    assertEquals(0, w(new byte[0]).size());
    assertEquals(1, w(new byte[1]).size());
    assertEquals(10, w(new byte[10]).size());
  }

  @Test
  void testGet() {
    Bytes v = w(new byte[] {1, 2, 3, 4});
    assertEquals((int) (byte) 1, (int) v.get(0));
    assertEquals((int) (byte) 2, (int) v.get(1));
    assertEquals((int) (byte) 3, (int) v.get(2));
    assertEquals((int) (byte) 4, (int) v.get(3));
  }

  @Test
  void testGetNegativeIndex() {
    assertThrows(IndexOutOfBoundsException.class, () -> w(new byte[] {1, 2, 3, 4}).get(-1));
  }

  @Test
  void testGetOutOfBound() {
    assertThrows(IndexOutOfBoundsException.class, () -> w(new byte[] {1, 2, 3, 4}).get(4));
  }

  @Test
  void testGetInt() {
    Bytes value = w(new byte[] {0, 0, 1, 0, -1, -1, -1, -1});

    // 0x00000100 = 256
    assertEquals(256, value.getInt(0));
    // 0x000100FF = 65536 + 255 = 65791
    assertEquals(65791, value.getInt(1));
    // 0x0100FFFF = 16777216 (2^24) + (65536 - 1) = 16842751
    assertEquals(16842751, value.getInt(2));
    // 0xFFFFFFFF = -1
    assertEquals(-1, value.getInt(4));
  }

  @Test
  void testGetIntNegativeIndex() {
    assertThrows(IndexOutOfBoundsException.class, () -> w(new byte[] {1, 2, 3, 4}).getInt(-1));
  }

  @Test
  void testGetIntOutOfBound() {
    assertThrows(IndexOutOfBoundsException.class, () -> w(new byte[] {1, 2, 3, 4}).getInt(4));
  }

  @Test
  void testGetIntNotEnoughBytes() {
    assertThrows(IndexOutOfBoundsException.class, () -> w(new byte[] {1, 2, 3, 4}).getInt(1));
  }

  @Test
  void testAsInt() {
    assertEquals(0, Bytes.EMPTY.toInt());
    Bytes value1 = w(new byte[] {0, 0, 1, 0});
    // 0x00000100 = 256
    assertEquals(256, value1.toInt());
    assertEquals(256, value1.slice(2).toInt());

    Bytes value2 = w(new byte[] {0, 1, 0, -1});
    // 0x000100FF = 65536 + 255 = 65791
    assertEquals(65791, value2.toInt());
    assertEquals(65791, value2.slice(1).toInt());

    Bytes value3 = w(new byte[] {1, 0, -1, -1});
    // 0x0100FFFF = 16777216 (2^24) + (65536 - 1) = 16842751
    assertEquals(16842751, value3.toInt());

    Bytes value4 = w(new byte[] {-1, -1, -1, -1});
    // 0xFFFFFFFF = -1
    assertEquals(-1, value4.toInt());
  }

  @Test
  void testAsIntTooManyBytes() {
    Throwable exception = assertThrows(IllegalArgumentException.class, () -> w(new byte[] {1, 2, 3, 4, 5}).toInt());
    assertEquals("Value of size 5 has more than 4 bytes", exception.getMessage());
  }

  @Test
  void testGetLong() {
    Bytes value1 = w(new byte[] {0, 0, 1, 0, -1, -1, -1, -1, 0, 0});
    // 0x00000100FFFFFFFF = (2^40) + (2^32) - 1 = 1103806595071
    assertEquals(1103806595071L, value1.getLong(0));
    // 0x 000100FFFFFFFF00 = (2^48) + (2^40) - 1 - 255 = 282574488338176
    assertEquals(282574488338176L, value1.getLong(1));

    Bytes value2 = w(new byte[] {-1, -1, -1, -1, -1, -1, -1, -1});
    assertEquals(-1L, value2.getLong(0));
  }

  @Test
  void testGetLongNegativeIndex() {
    assertThrows(IndexOutOfBoundsException.class, () -> w(new byte[] {1, 2, 3, 4, 5, 6, 7, 8}).getLong(-1));
  }

  @Test
  void testGetLongOutOfBound() {
    assertThrows(IndexOutOfBoundsException.class, () -> w(new byte[] {1, 2, 3, 4, 5, 6, 7, 8}).getLong(8));
  }

  @Test
  void testGetLongNotEnoughBytes() {
    assertThrows(IndexOutOfBoundsException.class, () -> w(new byte[] {1, 2, 3, 4}).getLong(0));
  }

  @Test
  void testAsLong() {
    assertEquals(0, Bytes.EMPTY.toLong());
    Bytes value1 = w(new byte[] {0, 0, 1, 0, -1, -1, -1, -1});
    // 0x00000100FFFFFFFF = (2^40) + (2^32) - 1 = 1103806595071
    assertEquals(1103806595071L, value1.toLong());
    assertEquals(1103806595071L, value1.slice(2).toLong());
    Bytes value2 = w(new byte[] {0, 1, 0, -1, -1, -1, -1, 0});
    // 0x000100FFFFFFFF00 = (2^48) + (2^40) - 1 - 255 = 282574488338176
    assertEquals(282574488338176L, value2.toLong());
    assertEquals(282574488338176L, value2.slice(1).toLong());

    Bytes value3 = w(new byte[] {-1, -1, -1, -1, -1, -1, -1, -1});
    assertEquals(-1L, value3.toLong());
  }

  @Test
  void testAsLongTooManyBytes() {
    Throwable exception =
        assertThrows(IllegalArgumentException.class, () -> w(new byte[] {1, 2, 3, 4, 5, 6, 7, 8, 9}).toLong());
    assertEquals("Value of size 9 has more than 8 bytes", exception.getMessage());
  }

  @Test
  void testSlice() {
    assertEquals(h("0x"), h("0x0123456789").slice(0, 0));
    assertEquals(h("0x"), h("0x0123456789").slice(2, 0));
    assertEquals(h("0x01"), h("0x0123456789").slice(0, 1));
    assertEquals(h("0x0123"), h("0x0123456789").slice(0, 2));

    assertEquals(h("0x4567"), h("0x0123456789").slice(2, 2));
    assertEquals(h("0x23456789"), h("0x0123456789").slice(1, 4));
  }

  @Test
  void testSliceNegativeOffset() {
    assertThrows(IndexOutOfBoundsException.class, () -> h("0x012345").slice(-1, 2));
  }

  @Test
  void testSliceOffsetOutOfBound() {
    assertThrows(IndexOutOfBoundsException.class, () -> h("0x012345").slice(3, 2));
  }

  @Test
  void testSliceTooLong() {
    Throwable exception = assertThrows(IllegalArgumentException.class, () -> h("0x012345").slice(1, 3));
    assertEquals(
        "Provided length 3 is too big: the value has size 3 and has only 2 bytes from 1",
        exception.getMessage());
  }

  @Test
  void testMutableCopy() {
    Bytes v = h("0x012345");
    MutableBytes mutableCopy = v.mutableCopy();

    // Initially, copy must be equal.
    assertEquals(mutableCopy, v);

    // Upon modification, original should not have been modified.
    mutableCopy.set(0, (byte) -1);
    assertNotEquals(mutableCopy, v);
    assertEquals(h("0x012345"), v);
    assertEquals(h("0xFF2345"), mutableCopy);
  }

  @Test
  void testCopyTo() {
    MutableBytes dest;

    // The follow does nothing, but simply making sure it doesn't throw.
    dest = MutableBytes.EMPTY;
    Bytes.EMPTY.copyTo(dest);
    assertEquals(Bytes.EMPTY, dest);

    dest = MutableBytes.create(1);
    of(1).copyTo(dest);
    assertEquals(h("0x01"), dest);

    dest = MutableBytes.create(1);
    of(10).copyTo(dest);
    assertEquals(h("0x0A"), dest);

    dest = MutableBytes.create(2);
    of(0xff, 0x03).copyTo(dest);
    assertEquals(h("0xFF03"), dest);

    dest = MutableBytes.create(4);
    of(0xff, 0x03).copyTo(dest.mutableSlice(1, 2));
    assertEquals(h("0x00FF0300"), dest);
  }

  @Test
  void testCopyToTooSmall() {
    Throwable exception =
        assertThrows(IllegalArgumentException.class, () -> of(1, 2, 3).copyTo(MutableBytes.create(2)));
    assertEquals("Cannot copy 3 bytes to destination of non-equal size 2", exception.getMessage());
  }

  @Test
  void testCopyToTooBig() {
    Throwable exception =
        assertThrows(IllegalArgumentException.class, () -> of(1, 2, 3).copyTo(MutableBytes.create(4)));
    assertEquals("Cannot copy 3 bytes to destination of non-equal size 4", exception.getMessage());
  }

  @Test
  void testCopyToWithOffset() {
    MutableBytes dest;

    dest = MutableBytes.wrap(new byte[] {1, 2, 3});
    Bytes.EMPTY.copyTo(dest, 0);
    assertEquals(h("0x010203"), dest);

    dest = MutableBytes.wrap(new byte[] {1, 2, 3});
    of(1).copyTo(dest, 1);
    assertEquals(h("0x010103"), dest);

    dest = MutableBytes.wrap(new byte[] {1, 2, 3});
    of(2).copyTo(dest, 0);
    assertEquals(h("0x020203"), dest);

    dest = MutableBytes.wrap(new byte[] {1, 2, 3});
    of(1, 1).copyTo(dest, 1);
    assertEquals(h("0x010101"), dest);

    dest = MutableBytes.create(4);
    of(0xff, 0x03).copyTo(dest, 1);
    assertEquals(h("0x00FF0300"), dest);
  }

  @Test
  void testCopyToWithOffsetTooSmall() {
    Throwable exception =
        assertThrows(IllegalArgumentException.class, () -> of(1, 2, 3).copyTo(MutableBytes.create(4), 2));
    assertEquals("Cannot copy 3 bytes, destination has only 2 bytes from index 2", exception.getMessage());
  }

  @Test
  void testCopyToWithNegativeOffset() {
    assertThrows(IndexOutOfBoundsException.class, () -> of(1, 2, 3).copyTo(MutableBytes.create(10), -1));
  }

  @Test
  void testCopyToWithOutOfBoundIndex() {
    assertThrows(IndexOutOfBoundsException.class, () -> of(1, 2, 3).copyTo(MutableBytes.create(10), 10));
  }

  @Test
  void testAppendTo() {
    testAppendTo(Bytes.EMPTY, Buffer.buffer(), Bytes.EMPTY);
    testAppendTo(Bytes.EMPTY, Buffer.buffer(h("0x1234").toArrayUnsafe()), h("0x1234"));
    testAppendTo(h("0x1234"), Buffer.buffer(), h("0x1234"));
    testAppendTo(h("0x5678"), Buffer.buffer(h("0x1234").toArrayUnsafe()), h("0x12345678"));
  }

  private void testAppendTo(Bytes toAppend, Buffer buffer, Bytes expected) {
    toAppend.appendTo(buffer);
    assertEquals(expected, Bytes.wrap(buffer.getBytes()));
  }

  @Test
  void testIsZero() {
    assertTrue(Bytes.EMPTY.isZero());
    assertTrue(Bytes.of(0).isZero());
    assertTrue(Bytes.of(0, 0, 0).isZero());

    assertFalse(Bytes.of(1).isZero());
    assertFalse(Bytes.of(1, 0, 0).isZero());
    assertFalse(Bytes.of(0, 0, 1).isZero());
    assertFalse(Bytes.of(0, 0, 1, 0, 0).isZero());
  }

  @Test
  void testIsEmpty() {
    assertTrue(Bytes.EMPTY.isEmpty());

    assertFalse(Bytes.of(0).isEmpty());
    assertFalse(Bytes.of(0, 0, 0).isEmpty());
    assertFalse(Bytes.of(1).isEmpty());
  }

  @Test
  void findsCommonPrefix() {
    Bytes v = Bytes.of(1, 2, 3, 4, 5, 6, 7);
    Bytes o = Bytes.of(1, 2, 3, 4, 4, 3, 2);
    assertEquals(4, v.commonPrefixLength(o));
    assertEquals(Bytes.of(1, 2, 3, 4), v.commonPrefix(o));
  }

  @Test
  void findsCommonPrefixOfShorter() {
    Bytes v = Bytes.of(1, 2, 3, 4, 5, 6, 7);
    Bytes o = Bytes.of(1, 2, 3, 4);
    assertEquals(4, v.commonPrefixLength(o));
    assertEquals(Bytes.of(1, 2, 3, 4), v.commonPrefix(o));
  }

  @Test
  void findsCommonPrefixOfLonger() {
    Bytes v = Bytes.of(1, 2, 3, 4);
    Bytes o = Bytes.of(1, 2, 3, 4, 4, 3, 2);
    assertEquals(4, v.commonPrefixLength(o));
    assertEquals(Bytes.of(1, 2, 3, 4), v.commonPrefix(o));
  }

  @Test
  void findsCommonPrefixOfSliced() {
    Bytes v = Bytes.of(1, 2, 3, 4).slice(2, 2);
    Bytes o = Bytes.of(3, 4, 3, 3, 2).slice(3, 2);
    assertEquals(1, v.commonPrefixLength(o));
    assertEquals(Bytes.of(3), v.commonPrefix(o));
  }

  @Test
  void testTrimLeadingZeroes() {
    assertEquals(h("0x"), h("0x").trimLeadingZeros());
    assertEquals(h("0x"), h("0x00").trimLeadingZeros());
    assertEquals(h("0x"), h("0x00000000").trimLeadingZeros());

    assertEquals(h("0x01"), h("0x01").trimLeadingZeros());
    assertEquals(h("0x01"), h("0x00000001").trimLeadingZeros());

    assertEquals(h("0x3010"), h("0x3010").trimLeadingZeros());
    assertEquals(h("0x3010"), h("0x00003010").trimLeadingZeros());

    assertEquals(h("0xFFFFFFFF"), h("0xFFFFFFFF").trimLeadingZeros());
    assertEquals(h("0xFFFFFFFF"), h("0x000000000000FFFFFFFF").trimLeadingZeros());
  }

  @Test
  void testHexString() {
    assertEquals("0x", h("0x").toShortHexString());
    assertEquals("0x", h("0x0000").toShortHexString());
    assertEquals("0x1000001", h("0x01000001").toShortHexString());

    assertEquals("0000", h("0x0000").toUnprefixedHexString());
    assertEquals("1234", h("0x1234").toUnprefixedHexString());
    assertEquals("0022", h("0x0022").toUnprefixedHexString());
  }

  @Test
  void slideToEnd() {
    assertEquals(Bytes.of(1, 2, 3, 4), Bytes.of(1, 2, 3, 4).slice(0));
    assertEquals(Bytes.of(2, 3, 4), Bytes.of(1, 2, 3, 4).slice(1));
    assertEquals(Bytes.of(3, 4), Bytes.of(1, 2, 3, 4).slice(2));
    assertEquals(Bytes.of(4), Bytes.of(1, 2, 3, 4).slice(3));
  }

  @Test
  void slicePastEndReturnsEmpty() {
    assertEquals(Bytes.EMPTY, Bytes.of(1, 2, 3, 4).slice(4));
    assertEquals(Bytes.EMPTY, Bytes.of(1, 2, 3, 4).slice(5));
  }

  @Test
  void testUpdate() throws NoSuchAlgorithmException {
    // Digest the same byte array in 4 ways:
    //  1) directly from the array
    //  2) after wrapped using the update() method
    //  3) after wrapped and copied using the update() method
    //  4) after wrapped but getting the byte manually
    // and check all compute the same digest.
    MessageDigest md1 = MessageDigest.getInstance("SHA-1");
    MessageDigest md2 = MessageDigest.getInstance("SHA-1");
    MessageDigest md3 = MessageDigest.getInstance("SHA-1");
    MessageDigest md4 = MessageDigest.getInstance("SHA-1");

    byte[] toDigest = new BigInteger("12324029423415041783577517238472017314").toByteArray();
    Bytes wrapped = w(toDigest);

    byte[] digest1 = md1.digest(toDigest);

    wrapped.update(md2);
    byte[] digest2 = md2.digest();

    wrapped.copy().update(md3);
    byte[] digest3 = md3.digest();

    for (int i = 0; i < wrapped.size(); i++)
      md4.update(wrapped.get(i));
    byte[] digest4 = md4.digest();

    assertArrayEquals(digest2, digest1);
    assertArrayEquals(digest3, digest1);
    assertArrayEquals(digest4, digest1);
  }

  @Test
  void testArrayExtraction() {
    // extractArray() and getArrayUnsafe() have essentially the same contract...
    testArrayExtraction(Bytes::toArray);
    testArrayExtraction(Bytes::toArrayUnsafe);

    // But on top of the basic, extractArray() guarantees modifying the returned array is safe from
    // impacting the original value (not that getArrayUnsafe makes no guarantees here one way or
    // another, so there is nothing to test).
    byte[] orig = new byte[] {1, 2, 3, 4};
    Bytes value = w(orig);
    byte[] extracted = value.toArray();
    assertArrayEquals(orig, extracted);
    Arrays.fill(extracted, (byte) -1);
    assertArrayEquals(extracted, new byte[] {-1, -1, -1, -1});
    assertArrayEquals(orig, new byte[] {1, 2, 3, 4});
    assertEquals(of(1, 2, 3, 4), value);
  }

  private void testArrayExtraction(Function<Bytes, byte[]> extractor) {
    byte[] bytes = new byte[0];
    assertArrayEquals(extractor.apply(Bytes.EMPTY), bytes);

    byte[][] toTest = new byte[][] {new byte[] {1}, new byte[] {1, 2, 3, 4, 5, 6}, new byte[] {-1, -1, 0, -1}};
    for (byte[] array : toTest) {
      assertArrayEquals(extractor.apply(w(array)), array);
    }

    // Test slightly more complex interactions
    assertArrayEquals(extractor.apply(w(new byte[] {1, 2, 3, 4, 5}).slice(2, 2)), new byte[] {3, 4});
    assertArrayEquals(extractor.apply(w(new byte[] {1, 2, 3, 4, 5}).slice(2, 0)), new byte[] {});
  }

  @Test
  void testToString() {
    assertEquals("0x", Bytes.EMPTY.toString());

    assertEquals("0x01", of(1).toString());
    assertEquals("0x0aff03", of(0x0a, 0xff, 0x03).toString());
  }

  @Test
  void testHasLeadingZeroByte() {
    assertFalse(Bytes.fromHexString("0x").hasLeadingZeroByte());
    assertTrue(Bytes.fromHexString("0x0012").hasLeadingZeroByte());
    assertFalse(Bytes.fromHexString("0x120012").hasLeadingZeroByte());
  }

  @Test
  void testNumberOfLeadingZeroBytes() {
    assertEquals(0, Bytes.fromHexString("0x12").numberOfLeadingZeroBytes());
    assertEquals(1, Bytes.fromHexString("0x0012").numberOfLeadingZeroBytes());
    assertEquals(2, Bytes.fromHexString("0x000012").numberOfLeadingZeroBytes());
    assertEquals(0, Bytes.fromHexString("0x").numberOfLeadingZeroBytes());
    assertEquals(1, Bytes.fromHexString("0x00").numberOfLeadingZeroBytes());
    assertEquals(2, Bytes.fromHexString("0x0000").numberOfLeadingZeroBytes());
    assertEquals(3, Bytes.fromHexString("0x000000").numberOfLeadingZeroBytes());
  }

  @Test
  void testNumberOfTrailingZeroBytes() {
    assertEquals(0, Bytes.fromHexString("0x12").numberOfTrailingZeroBytes());
    assertEquals(1, Bytes.fromHexString("0x1200").numberOfTrailingZeroBytes());
    assertEquals(2, Bytes.fromHexString("0x120000").numberOfTrailingZeroBytes());
    assertEquals(0, Bytes.fromHexString("0x").numberOfTrailingZeroBytes());
    assertEquals(1, Bytes.fromHexString("0x00").numberOfTrailingZeroBytes());
    assertEquals(2, Bytes.fromHexString("0x0000").numberOfTrailingZeroBytes());
    assertEquals(3, Bytes.fromHexString("0x000000").numberOfTrailingZeroBytes());
  }

  @Test
  void testHasLeadingZeroBit() {
    assertFalse(Bytes.fromHexString("0x").hasLeadingZero());
    assertTrue(Bytes.fromHexString("0x01").hasLeadingZero());
    assertFalse(Bytes.fromHexString("0xFF0012").hasLeadingZero());
  }

  @Test
  void testEquals() {
    SecureRandom random = new SecureRandom();
    byte[] key = new byte[32];
    random.nextBytes(key);
    Bytes b = w(key);
    Bytes b2 = w(key);
    assertEquals(b.hashCode(), b2.hashCode());
  }

  @Test
  void testEqualsWithOffset() {
    SecureRandom random = new SecureRandom();
    byte[] key = new byte[32];
    random.nextBytes(key);
    Bytes b = w(key).slice(16, 4);
    Bytes b2 = w(key).slice(16, 8).slice(0, 4);
    assertEquals(b, b2);
  }

  @Test
  void testHashCode() {
    SecureRandom random = new SecureRandom();
    byte[] key = new byte[32];
    random.nextBytes(key);
    Bytes b = w(key);
    Bytes b2 = w(key);
    assertEquals(b.hashCode(), b2.hashCode());
  }

  @Test
  void testHashCodeWithOffset() {
    SecureRandom random = new SecureRandom();
    byte[] key = new byte[32];
    random.nextBytes(key);
    Bytes b = w(key).slice(16, 16);
    Bytes b2 = w(key).slice(16, 16);
    assertEquals(b.hashCode(), b2.hashCode());
  }

  @Test
  void testHashCodeWithByteBufferWrappingBytes() {
    SecureRandom random = new SecureRandom();
    byte[] key = new byte[32];
    random.nextBytes(key);
    Bytes b = w(key);
    Bytes other = Bytes.wrapByteBuffer(ByteBuffer.wrap(key));
    assertEquals(b.hashCode(), other.hashCode());
  }

  @Test
  void testEqualsWithByteBufferWrappingBytes() {
    SecureRandom random = new SecureRandom();
    byte[] key = new byte[32];
    random.nextBytes(key);
    Bytes b = w(key);
    Bytes other = Bytes.wrapByteBuffer(ByteBuffer.wrap(key));
    assertEquals(b, other);
  }

  @Test
  void testHashCodeWithBufferWrappingBytes() {
    SecureRandom random = new SecureRandom();
    byte[] key = new byte[32];
    random.nextBytes(key);
    Bytes b = w(key);
    Bytes other = Bytes.wrapBuffer(Buffer.buffer(key));
    assertEquals(b.hashCode(), other.hashCode());
  }

  @Test
  void testEqualsWithBufferWrappingBytes() {
    SecureRandom random = new SecureRandom();
    byte[] key = new byte[32];
    random.nextBytes(key);
    Bytes b = w(key);
    Bytes other = Bytes.wrapBuffer(Buffer.buffer(key));
    assertEquals(b, other);
  }

  @Test
  void testHashCodeWithByteBufWrappingBytes() {
    SecureRandom random = new SecureRandom();
    byte[] key = new byte[32];
    random.nextBytes(key);
    Bytes b = w(key);
    Bytes other = Bytes.wrapByteBuf(Unpooled.copiedBuffer(key));
    assertEquals(b.hashCode(), other.hashCode());
  }

  @Test
  void testEqualsWithByteBufWrappingBytes() {
    SecureRandom random = new SecureRandom();
    byte[] key = new byte[32];
    random.nextBytes(key);
    Bytes b = w(key);
    Bytes other = Bytes.wrapByteBuf(Unpooled.copiedBuffer(key));
    assertEquals(b, other);
  }
}
