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