/*
 * 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.iotdb.tsfile.utils;

import org.apache.iotdb.tsfile.constant.TestConstant;

import org.junit.Assert;
import org.junit.Test;

import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;

public class BytesUtilsTest {

  private Random r = new Random(System.currentTimeMillis());

  @Test
  public void testIntToBytes() {
    int b = 123;
    byte[] bb = BytesUtils.intToBytes(b);
    int bf = BytesUtils.bytesToInt(bb);
    assertEquals("testBytesToFloat", b, bf);
  }

  @Test
  public void testIntToBytesWithBytesArray() {
    int b1 = 123;
    int b2 = 234;
    byte[] ret = new byte[8];
    BytesUtils.intToBytes(b1, ret, 0);
    BytesUtils.intToBytes(b2, ret, 4);
    int rb1 = BytesUtils.bytesToInt(ret, 0);
    int rb2 = BytesUtils.bytesToInt(ret, 4);
    assertEquals("testBytesToFloat", b1, rb1);
    assertEquals("testBytesToFloat", b2, rb2);
  }

  @Test
  public void testFloatToBytes() {
    // fail("NotFilter yet implemented");
    float b = 25.0f;
    byte[] bb = BytesUtils.floatToBytes(b);
    float bf = BytesUtils.bytesToFloat(bb);
    assertEquals("testBytesToFloat", b, bf, TestConstant.float_min_delta);
  }

  @Test
  public void testFloatToBytesWithBytesArray() {
    float b1 = 123.123f;
    float b2 = 234.323f;
    byte[] ret = new byte[8];
    BytesUtils.floatToBytes(b1, ret, 0);
    BytesUtils.floatToBytes(b2, ret, 4);
    float rb1 = BytesUtils.bytesToFloat(ret, 0);
    float rb2 = BytesUtils.bytesToFloat(ret, 4);
    assertEquals(b1, rb1, TestConstant.float_min_delta);
    assertEquals(b2, rb2, TestConstant.float_min_delta);
  }

  @Test
  public void testBoolToBytes() {
    boolean b = true;
    byte[] bb = BytesUtils.boolToBytes(b);
    boolean bf = BytesUtils.bytesToBool(bb);
    assertEquals("testBoolToBytes", b, bf);
  }

  @Test
  public void testBytesToBool() {
    boolean b = false;
    byte[] bb = BytesUtils.boolToBytes(b);
    boolean bf = BytesUtils.bytesToBool(bb);
    assertEquals("testBytesToBool", b, bf);
  }

  @Test
  public void testBoolToBytesWithBytesArray() {
    boolean b1 = true;
    boolean b2 = false;
    byte[] ret = new byte[2];
    BytesUtils.boolToBytes(b1, ret, 0);
    BytesUtils.boolToBytes(b2, ret, 1);
    boolean rb1 = BytesUtils.bytesToBool(ret, 0);
    boolean rb2 = BytesUtils.bytesToBool(ret, 1);
    assertEquals(b1, rb1);
    assertEquals(b2, rb2);
  }

  @Test
  public void testlongToBytes() {
    long lNum = 32143422454243342L;
    long iNum = 1032423424L;
    long lSNum = 10;
    assertEquals(lNum, BytesUtils.bytesToLong(BytesUtils.longToBytes(lNum, 8), 8));
    assertEquals(iNum, BytesUtils.bytesToLong(BytesUtils.longToBytes(iNum, 8), 8));
    assertEquals(iNum, BytesUtils.bytesToLong(BytesUtils.longToBytes(iNum, 4), 4));
    assertEquals(lSNum, BytesUtils.bytesToLong(BytesUtils.longToBytes(lSNum, 1), 1));
  }

  @Test
  public void testLongToBytesWithBytesArray() {
    long b1 = 3214342243342L;
    long b2 = 1032423424L;
    byte[] ret = new byte[16];
    BytesUtils.longToBytes(b1, ret, 0);
    BytesUtils.longToBytes(b2, ret, 8);
    long rb1 = BytesUtils.bytesToLongFromOffset(ret, 8, 0);
    long rb2 = BytesUtils.bytesToLongFromOffset(ret, 8, 8);
    assertEquals(b1, rb1);
    assertEquals(b2, rb2);
  }

  @Test
  public void bytesToLongOffsetTest() {
    long l = 2454243342L;
    int width = 64 - Long.numberOfLeadingZeros(l);
    byte[] bs = new byte[width * 2];
    BytesUtils.longToBytes(l, bs, 0, width);
    assertEquals(l, BytesUtils.bytesToLong(bs, 0, width));
  }

  @Test
  public void bytesToIntOffsetTest1() {
    int l1 = 123;
    int width1 = 64 - Integer.numberOfLeadingZeros(l1);
    int l2 = -124;
    int width2 = 64 - Integer.numberOfLeadingZeros(l2);
    byte[] bs = new byte[1000];
    BytesUtils.intToBytes(l1, bs, 0, width1);
    int res_val1_1 = BytesUtils.bytesToInt(bs, 0, width1);
    BytesUtils.intToBytes(l2, bs, width1, width2);
    int res_val1_2 = BytesUtils.bytesToInt(bs, 0, width1);
    Assert.assertEquals(res_val1_1, res_val1_2);
  }

  @Test
  public void bytesToLongOffsetTest1() {
    long l1 = 1600650710304L;
    int width1 = 64 - Long.numberOfLeadingZeros(l1);
    long l2 = -16L;
    int width2 = 64 - Long.numberOfLeadingZeros(l2);
    byte[] bs = new byte[1000];
    BytesUtils.longToBytes(l1, bs, 0, width1);
    long res_val1_1 = BytesUtils.bytesToLong(bs, 0, width1);
    BytesUtils.longToBytes(l2, bs, width1, width2);
    long res_val1_2 = BytesUtils.bytesToLong(bs, 0, width1);
    Assert.assertEquals(res_val1_1, res_val1_2);
  }

  @Test
  public void bytesToLongOffsetTest2() {
    long l1 = 123L;
    int width1 = 64 - Long.numberOfLeadingZeros(l1);
    long l2 = -123L;
    int width2 = 64 - Long.numberOfLeadingZeros(l2);
    long l3 = 123L;
    int width3 = 64 - Long.numberOfLeadingZeros(l3);
    byte[] bs = new byte[1000];
    BytesUtils.longToBytes(l1, bs, 0, width1);
    assertEquals(l1, BytesUtils.bytesToLong(bs, 0, width1));
    BytesUtils.longToBytes(l2, bs, width1, width2);
    BytesUtils.longToBytes(l3, bs, width1 + width2, width3);
    assertEquals(l1, BytesUtils.bytesToLong(bs, 0, width1));
    assertEquals(l2, BytesUtils.bytesToLong(bs, width1, width2));
    assertEquals(l3, BytesUtils.bytesToLong(bs, width1 + width2, width3));
  }

  @Test
  public void readLongTest() throws IOException {
    long l = 32143422454243342L;
    byte[] bs = BytesUtils.longToBytes(l);
    InputStream in = new ByteArrayInputStream(bs);
    assertEquals(l, BytesUtils.readLong(in));
  }

  @Test
  public void testDoubleToBytes() {
    double b1 = 2745687.1253123d;
    byte[] ret = BytesUtils.doubleToBytes(b1);
    double rb1 = BytesUtils.bytesToDouble(ret);
    assertEquals(b1, rb1, TestConstant.float_min_delta);
  }

  @Test
  public void testDoubleToBytesWithBytesArray() {
    double b1 = 112357.548799d;
    double b2 = 2745687.1253123d;
    byte[] ret = new byte[16];
    BytesUtils.doubleToBytes(b1, ret, 0);
    BytesUtils.doubleToBytes(b2, ret, 8);
    double rb1 = BytesUtils.bytesToDouble(ret, 0);
    double rb2 = BytesUtils.bytesToDouble(ret, 8);
    assertEquals(b1, rb1, TestConstant.double_min_delta);
    assertEquals(b2, rb2, TestConstant.double_min_delta);
  }

  @Test
  public void testStringToBytes() {
    String b = "lqfkgv12KLDJSL1@#%";
    byte[] ret = BytesUtils.stringToBytes(b);
    String rb1 = BytesUtils.bytesToString(ret);
    assertTrue(b.equals(rb1));
  }

  @Test
  public void testConcatByteArray() {
    List<byte[]> list = new ArrayList<byte[]>();
    float f1 = 12.4f;
    boolean b1 = true;
    list.add(BytesUtils.floatToBytes(f1));
    list.add(BytesUtils.boolToBytes(b1));
    byte[] ret = BytesUtils.concatByteArray(list.get(0), list.get(1));
    float rf1 = BytesUtils.bytesToFloat(ret, 0);
    boolean rb1 = BytesUtils.bytesToBool(ret, 4);
    assertEquals(f1, rf1, TestConstant.float_min_delta);
    assertEquals(b1, rb1);
  }

  @Test
  public void testConcatByteArrayList() {
    List<byte[]> list = new ArrayList<byte[]>();
    float f1 = 12.4f;
    boolean b1 = true;
    int i1 = 12;
    list.add(BytesUtils.floatToBytes(f1));
    list.add(BytesUtils.boolToBytes(b1));
    list.add(BytesUtils.intToBytes(i1));
    byte[] ret = BytesUtils.concatByteArrayList(list);
    float rf1 = BytesUtils.bytesToFloat(ret, 0);
    boolean rb1 = BytesUtils.bytesToBool(ret, 4);
    int ri1 = BytesUtils.bytesToInt(ret, 5);
    assertEquals(f1, rf1, TestConstant.float_min_delta);
    assertEquals(b1, rb1);
    assertEquals(i1, ri1);
  }

  @Test
  public void testSubBytes() {
    List<byte[]> list = new ArrayList<byte[]>();
    float f1 = 12.4f;
    boolean b1 = true;
    int i1 = 12;
    list.add(BytesUtils.floatToBytes(f1));
    list.add(BytesUtils.boolToBytes(b1));
    list.add(BytesUtils.intToBytes(i1));
    byte[] ret = BytesUtils.concatByteArrayList(list);
    boolean rb1 = BytesUtils.bytesToBool(BytesUtils.subBytes(ret, 4, 1));
    int ri1 = BytesUtils.bytesToInt(BytesUtils.subBytes(ret, 5, 4));
    assertEquals(b1, rb1);
    assertEquals(i1, ri1);
  }

  @Test
  public void testGetByteN() {
    byte src = 120;
    byte dest = 0;
    for (int i = 0; i < 64; i++) {
      int a = BytesUtils.getByteN(src, i);
      dest = BytesUtils.setByteN(dest, i, a);
    }
    assertEquals(src, dest);
  }

  @Test
  public void testGetLongN() {
    long src = (long) Math.pow(2, 33);
    long dest = 0;
    for (int i = 0; i < 64; i++) {
      int a = BytesUtils.getLongN(src, i);
      dest = BytesUtils.setLongN(dest, i, a);
    }
    assertEquals(src, dest);
  }

  @Test
  public void testGetIntN() {
    int src = 54243342;
    int dest = 0;
    for (int i = 0; i < 32; i++) {
      int a = BytesUtils.getIntN(src, i);
      dest = BytesUtils.setIntN(dest, i, a);
    }
    assertEquals(src, dest);
  }

  @Test
  public void testIntToBytesWithWidth() {
    int b1 = (1 << 22) - 1413;
    int b2 = (1 << 22) - 3588;
    int b3 = (1 << 22) - 1435;
    int b4 = (1 << 22) - 85476;
    byte[] ret = new byte[12];
    BytesUtils.intToBytes(b1, ret, 0, 24);
    BytesUtils.intToBytes(b2, ret, 24, 24);
    BytesUtils.intToBytes(b3, ret, 48, 24);
    BytesUtils.intToBytes(b4, ret, 72, 24);
    int rb1 = BytesUtils.bytesToInt(ret, 0, 24);
    int rb2 = BytesUtils.bytesToInt(ret, 24, 24);
    int rb3 = BytesUtils.bytesToInt(ret, 48, 24);
    int rb4 = BytesUtils.bytesToInt(ret, 72, 24);
    assertEquals("testIntToBytesWithWidth1", b1, rb1);
    assertEquals("testIntToBytesWithWidth2", b2, rb2);
    assertEquals("testIntToBytesWithWidth3", b3, rb3);
    assertEquals("testIntToBytesWithWidth4", b4, rb4);
  }

  @Test
  public void testLongToBytesWithWidth() {
    int bitLen = 42;
    long basic = (1 << 30) * 2l;
    long b1 = (1 << (bitLen % 32)) * basic + r.nextInt();
    long b2 = (1 << (bitLen % 32)) * basic + r.nextInt();
    long b3 = (1 << (bitLen % 32)) * basic + r.nextInt();
    long b4 = (1 << (bitLen % 32)) * basic + r.nextInt();
    byte[] ret = new byte[(int) Math.ceil(bitLen * 4.0 / 8.0)];
    BytesUtils.longToBytes(b1, ret, bitLen * 0, bitLen);
    BytesUtils.longToBytes(b2, ret, bitLen * 1, bitLen);
    BytesUtils.longToBytes(b3, ret, bitLen * 2, bitLen);
    BytesUtils.longToBytes(b4, ret, bitLen * 3, bitLen);
    long rb1 = BytesUtils.bytesToLong(ret, bitLen * 0, bitLen);
    long rb2 = BytesUtils.bytesToLong(ret, bitLen * 1, bitLen);
    long rb3 = BytesUtils.bytesToLong(ret, bitLen * 2, bitLen);
    long rb4 = BytesUtils.bytesToLong(ret, bitLen * 3, bitLen);
    assertEquals("testIntToBytesWithWidth1", b1, rb1);
    assertEquals("testIntToBytesWithWidth2", b2, rb2);
    assertEquals("testIntToBytesWithWidth3", b3, rb3);
    assertEquals("testIntToBytesWithWidth4", b4, rb4);
  }

  private void intToBinaryShowForTest(int src) {
    for (int i = 31; i >= 0; i--) {
      if ((src & (1 << i)) != 0) {
        System.out.print(1);
      } else {
        System.out.print(0);
      }
      if ((i % 8) == 0) {
        System.out.print(" ");
      }
    }
    System.out.print("\n");
  }

  private void longToBinaryShowForTest(long src) {
    for (int i = 63; i >= 0; i--) {
      System.out.print(BytesUtils.getLongN(src, i));
      if ((i % 8) == 0) {
        System.out.print(" ");
      }
    }
    System.out.print("\n");
  }

  private void byteArrayToBinaryShowForTest(byte[] src) {
    for (byte b : src) {
      for (int i = 8; i >= 0; i--) {
        if ((b & (1 << i)) != 0) {
          System.out.print(1);
        } else {
          System.out.print(0);
        }
      }
      System.out.print(" ");
    }
    System.out.print("\n");
  }

  @Test
  public void testReadInt() throws IOException {
    int l = r.nextInt();
    byte[] bs = BytesUtils.intToBytes(l);
    InputStream in = new ByteArrayInputStream(bs);
    assertEquals(l, BytesUtils.readInt(in));
  }

  @Test
  public void testReadLong() throws IOException {
    long l = r.nextLong();
    byte[] bs = BytesUtils.longToBytes(l);
    InputStream in = new ByteArrayInputStream(bs);
    assertEquals(l, BytesUtils.readLong(in));
  }

  @Test
  public void testReadFloat() throws IOException {
    float l = r.nextFloat();
    byte[] bs = BytesUtils.floatToBytes(l);
    InputStream in = new ByteArrayInputStream(bs);
    assertEquals(l, BytesUtils.readFloat(in), TestConstant.float_min_delta);
  }

  @Test
  public void testReadDouble() throws IOException {
    double l = r.nextDouble();
    byte[] bs = BytesUtils.doubleToBytes(l);
    InputStream in = new ByteArrayInputStream(bs);
    assertEquals(l, BytesUtils.readDouble(in), TestConstant.double_min_delta);
  }

  @Test
  public void testReadBool() throws IOException {
    boolean l = r.nextBoolean();
    byte[] bs = BytesUtils.boolToBytes(l);
    InputStream in = new ByteArrayInputStream(bs);
    assertEquals(l, BytesUtils.readBool(in));
  }
}
