/*
 * 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.datasketches.memory.internal;

import static org.testng.Assert.assertEquals;
import static org.testng.Assert.assertTrue;
import static org.testng.Assert.fail;

import java.util.ArrayList;
import java.util.List;

import org.testng.annotations.Test;


/**
 * @author Lee Rhodes
 */
public class UnsafeUtilTest {
  long testField = 1; //Do not remove & cannot be static. Used in reflection check.


  @Test
  public void checkJdkString() {
    String jdkVer;
    int[] p = new int[2];
    String[] good1_Strings = {"1.8.0_121", "8", "9", "10", "11", "12", "13"};
    int len = good1_Strings.length;
    for (int i = 0; i < len; i++) {
      jdkVer = good1_Strings[i];
      p = UnsafeUtil.parseJavaVersion(jdkVer);
      UnsafeUtil.checkJavaVersion(jdkVer, p[0], p[1]);
      int jdkMajor = (p[0] == 1) ? p[1] : p[0]; //model the actual JDK_MAJOR
      if (p[0] == 1) { assertTrue(jdkMajor == p[1]); }
      if (p[0] > 1 ) { assertTrue(jdkMajor == p[0]); }
    }
    try {
      jdkVer = "14.0.4"; //ver 14 string
      p = UnsafeUtil.parseJavaVersion(jdkVer);
      UnsafeUtil.checkJavaVersion(jdkVer, p[0], p[1]);
      fail();
    } catch (IllegalArgumentException e) {
      println("" + e);
    }

    try {
      jdkVer = "1.7.0_80"; //1.7 string
      p = UnsafeUtil.parseJavaVersion(jdkVer);
      UnsafeUtil.checkJavaVersion(jdkVer, p[0], p[1]);
      fail();
    } catch (IllegalArgumentException e) {
      println("" + e);
    }
    try {
      jdkVer = "1.6.0_65"; //valid string but < 1.7
      p = UnsafeUtil.parseJavaVersion(jdkVer);
      UnsafeUtil.checkJavaVersion(jdkVer, p[0], p[1]); //throws
      fail();
    } catch (IllegalArgumentException e) {
      println("" + e);
    }
    try {
      jdkVer = "b"; //invalid string
      p = UnsafeUtil.parseJavaVersion(jdkVer);
      UnsafeUtil.checkJavaVersion(jdkVer, p[0], p[1]); //throws
      fail();
    } catch (IllegalArgumentException e) {
      println("" + e);
    }
    try {
      jdkVer = ""; //invalid string
      p = UnsafeUtil.parseJavaVersion(jdkVer);
      UnsafeUtil.checkJavaVersion(jdkVer, p[0], p[1]); //throws
      fail();
    } catch (IllegalArgumentException e) {
      println("" + e);
    }
  }

  @Test
  public void checkFieldOffset() {
    assertEquals(testField, 1);
    long offset = UnsafeUtil.getFieldOffset(this.getClass(), "testField");
    assertEquals(offset, 16);
    try {
      offset = UnsafeUtil.getFieldOffset(this.getClass(), "testField2");
      fail();
    } catch (IllegalStateException e) {
      //OK
    }
  }

  @Test(expectedExceptions = IllegalArgumentException.class)
  public void checkInts() {
    Ints.checkedCast(1L << 32);
  }

  @SuppressWarnings("restriction")
  @Test
  public void checkArrayBaseOffset()
  {
    final List<Class<?>> classes = new ArrayList<>();
    classes.add(byte[].class);
    classes.add(int[].class);
    classes.add(long[].class);
    classes.add(float[].class);
    classes.add(double[].class);
    classes.add(boolean[].class);
    classes.add(short[].class);
    classes.add(char[].class);
    classes.add(Object[].class);
    classes.add(byte[][].class); // An array type that is not cached

    for (Class<?> clazz : classes) {
      assertEquals(
          UnsafeUtil.getArrayBaseOffset(clazz),
          UnsafeUtil.unsafe.arrayBaseOffset(clazz),
          clazz.getTypeName()
      );
    }
  }

  @Test
  public void printlnTest() {
    println("PRINTING: "+this.getClass().getName());
  }

  /**
   * @param s String to print
   */
  static void println(final String s) {
    //System.out.println(s);
  }

}
