/*=========================================================================
 * Copyright (c) 2010-2014 Pivotal Software, Inc. All Rights Reserved.
 * This product is protected by U.S. and international copyright
 * and intellectual property laws. Pivotal products are covered by
 * one or more patents listed at http://www.pivotal.io/patents.
 *=========================================================================
 */

package com.gemstone.gemfire.internal.util;

import java.util.Arrays;

import com.gemstone.gemfire.internal.lang.StringUtils;
import com.gemstone.gemfire.internal.offheap.annotations.Unretained;

/**
 * @author John Blum
 * @author jpenney
 *
 * Handle some simple editing of fixed-length arrays.
 *
 * TODO use Java 1.5 template classes to simplify this interface
 *
 */
public abstract class ArrayUtils {

  /**
   * Gets the element at index in the array in a bound-safe manner.  If index is not a valid index in the given array,
   * then the default value is returned.
   * <p/>
   * @param <T> the class type of the elements in the array.
   * @param array the array from which the element at index is retrieved.
   * @param index the index into the array to retrieve the element.
   * @param defaultValue the default value of element type to return in the event that the array index is invalid.
   * @return the element at index from the array or the default value if the index is invalid.
   */
  public static <T> T getElementAtIndex(T[] array, int index, T defaultValue) {
    try {
      return array[index];
    }
    catch (ArrayIndexOutOfBoundsException ignore) {
      return defaultValue;
    }
  }

  /**
   * Gets the first element from the given array or null if the array reference is null or the array length is 0.
   * <p/>
   * @param <T> the Class type of the elements in the array.
   * @param array the array of elements from which to retrieve the first element.
   * @return the first element from the array or null if either the array reference is null or the array length is 0.
   */
  public static <T> T getFirst(final T... array) {
    return (array != null && array.length > 0 ? array[0] : null);
  }

  /**
   * Converts the specified Object array into a String representation.
   * <p/>
   * @param array the Object array of elements to convert to a String.
   * @return a String representation of the Object array.
   * @see java.lang.StringBuilder
   */
  public static String toString(final Object... array) {
    final StringBuilder buffer = new StringBuilder("[");
    int count = 0;

    if (array != null) {
      for (final Object element : array) {
        buffer.append(count++ > 0 ? ", " : StringUtils.EMPTY_STRING).append(element);
      }
    }

    buffer.append("]");

    return buffer.toString();
  }

  public static String toString(final String... array) {
    return toString((Object[])array); 
  }
  
  /**
   * Insert an element into an array.  The element is inserted at the
   * given position, all elements afterwards are moved to the right.
   *
   * @param originalArray array to insert into
   * @param pos position at which to insert the element
   * @param element element to add
   * @return the new array
   */
  public static Object[] insert(Object[] originalArray, int pos, Object element) {
    Object[] newArray = (Object[]) java.lang.reflect.Array.newInstance(
      originalArray.getClass().getComponentType(), originalArray.length + 1);

    // Test Cases (proof of correctness by examining corner cases)
    // 1) A B C D insert at 0: expect X A B C D
    // 2) A B C D insert at 2: expect A B X C D
    // 3) A B C D insert at 4: expect A B C D X

    // copy everything before the given position
    if (pos > 0) {
      System.arraycopy(originalArray, 0, newArray, 0, pos); // does not copy originalArray[pos], where we insert
    }

    // 1) A B C D insert at 0: no change, ". . . . ."
    // 2) A B C D insert at 2: copy "A B", "A B . . ."
    // 3) A B C D insert at 4: copy "A B C D", "A B C D ."

    // insert
    newArray[pos] = element;

    // 1) A B C D insert at 0: "X . . . ."
    // 2) A B C D insert at 2: "A B X . ."
    // 3) A B C D insert at 4: "A B C D X" (all done)

    // copy remaining elements
    if (pos < originalArray.length) {
      System.arraycopy(originalArray, pos, // originalArray[pos] first element copied
          newArray, pos + 1, // newArray[pos + 1] first destination
          originalArray.length - pos); // number of elements left
    }

    // 1) A B C D insert at 0: "A B C D" copied at 1: "X A B C D"
    // 2) A B C D insert at 2: "C D" copied at 3: "A B X C D"
    // 3) A B C D insert at 4: no change
    return newArray;
  }

  /**
   * Remove element from an array.  The element is removed at the
   * specified position, and all remaining elements are moved to the left.
   *
   * @param originalArray array to remove from
   * @param pos position to remove
   * @return the new array
   */
  public static Object[] remove(Object[] originalArray, int pos) {
    Object[] newArray = (Object[])java.lang.reflect.Array.newInstance(
      originalArray.getClass().getComponentType(), originalArray.length - 1);

    // Test cases: (proof of correctness)
    // 1) A B C D E remove 0: expect "B C D E"
    // 2) A B C D E remove 2: expect "A B D E"
    // 3) A B C D E remove 4: expect "A B C D"

    // Copy everything before
    if (pos > 0) {
      System.arraycopy(originalArray, 0, newArray, 0, pos); // originalArray[pos - 1] is last element copied
    }

    // 1) A B C D E remove 0: no change, ". . . ."
    // 2) A B C D E remove 2: "A B"  copied at beginning: "A B . ."
    // 3) A B C D E remove 4: "A B C D" copied (all done)

    // Copy everything after
    if (pos < originalArray.length - 1) {
      System.arraycopy(originalArray, pos + 1, // originalArray[pos + 1] is first element copied
          newArray, pos, // first position to copy into
          originalArray.length - 1 - pos);
    }

    // 1) A B C D E remove 0: "B C D E" copied into to position 0
    // 2) A B C D E remove 2: "D E" copied into position 2: "A B D E"
    // 3) A B C D E remove 4: no change
    return newArray;
  }

  public static String objectRefString(Object obj) {
    return obj != null ? obj.getClass().getSimpleName() + '@'
        + Integer.toHexString(System.identityHashCode(obj)) : "(null)";
  }

  public static void objectRefString(Object obj, StringBuilder sb) {
    if (obj != null) {
      sb.append(obj.getClass().getSimpleName()).append('@')
          .append(Integer.toHexString(System.identityHashCode(obj)));
    }
    else {
      sb.append("(null)");
    }
  }

  /** Get proper string for an object including arrays. */
  public static String objectString(Object obj) {
    StringBuilder sb = new StringBuilder();
    objectString(obj, sb);
    return sb.toString();
  }

  /** Get proper string for an object including arrays. */
  public static void objectString(Object obj, StringBuilder sb) {
    if (obj instanceof Object[]) {
      sb.append('(');
      boolean first = true;
      for (Object o : (Object[])obj) {
        if (!first) {
          sb.append(',');
        }
        else {
          first = false;
        }
        objectString(o, sb);
      }
      sb.append(')');
    }
    else {
      objectStringWithBytes(obj, sb);
    }
  }

  /**
   * Get proper string for an an object including arrays with upto one dimension
   * of arrays.
   */
  public static String objectStringNonRecursive(@Unretained Object obj) {
    StringBuilder sb = new StringBuilder();
    objectStringNonRecursive(obj, sb);
    return sb.toString();
  }  
  
  public static boolean areByteArrayArrayEquals(byte[][] v1, byte[][] v2) {
    boolean areEqual = false;
    if (v1.length == v2.length) {
      areEqual = true;
      for (int index = 0; index < v1.length; ++index) {
        if (!Arrays.equals(v1[index], v2[index])) {
          areEqual = false;
          break;
        }
      }
    }
    return areEqual;
  }

  /**
   * Get proper string for an an object including arrays with upto one dimension
   * of arrays.
   */
  public static void objectStringNonRecursive(@Unretained Object obj, StringBuilder sb) {
    if (obj instanceof Object[]) {
      sb.append('(');
      boolean first = true;
      for (Object o : (Object[])obj) {
        if (!first) {
          sb.append(',');
          sb.append(o);
        }
        else {
          first = false;
          // for SQLFire show the first byte[] for byte[][] storage
          objectStringWithBytes(o, sb);
        }
      }
      sb.append(')');
    }
    else {
      objectStringWithBytes(obj, sb);
    }
  }

  private static void objectStringWithBytes(@Unretained Object obj, StringBuilder sb) {
    if (obj instanceof byte[]) {
      sb.append('(');
      boolean first = true;
      final byte[] bytes = (byte[])obj;
      int numBytes = 0;
      for (byte b : bytes) {
        if (!first) {
          sb.append(',');
        }
        else {
          first = false;
        }
        sb.append(b);
        // terminate with ... for large number of bytes
        if (numBytes++ >= 5000 && numBytes < bytes.length) {
          sb.append(" ...");
          break;
        }
      }
      sb.append(')');
    }
    else {
      sb.append(obj);
    }
  }

  /**
   * Check if two objects, possibly null, are equal. Doesn't really belong to
   * this class...
   */
  public static boolean objectEquals(Object o1, Object o2) {
    if (o1 == o2) {
      return true;
    }
    if (o1 == null) {
      return false;
    }
    return o1.equals(o2);
  }

  /**
   * Converts the primitive int array into an Integer wrapper object array.
   * </p>
   * @param array the primitive int array to convert into an Integer wrapper object array.
   * @return an Integer array containing the values from the elements in the primitive int array.
   */
  public static Integer[] toIntegerArray(final int[] array) {
    final Integer[] integerArray = new Integer[array == null ? 0 : array.length];

    if (array != null) {
      for (int index = 0; index < array.length; index++) {
        integerArray[index] = array[index];
      }
    }

    return integerArray;
  }
  
  /**
   * Converts a double byte array into a double Byte array. 
   * 
   * @param array the double byte array to convert into double Byte array
   * @return a double array of Byte objects containing values from the double byte array
   */
  public static Byte[][] toByteArray(final byte[][] array) {
    if (array == null) {
      return null;
    }
    final Byte[][] byteArray = new Byte[array.length][];
    for (int i = 0; i < array.length; i++) {
      byteArray[i] = new Byte[array[i].length];
      for (int j = 0; j < array[i].length; j++) {
        byteArray[i][j] = array[i][j];
      }
    }
    return byteArray;
  }

  /**
   * Converts a double Byte array into a double byte array. 
   * 
   * @param byteArray the double Byte array to convert into a double byte array
   * @return a double byte array containing byte values from the double Byte array
   */
  public static byte[][] toBytes(final Byte[][] byteArray) {
    if (byteArray == null) {
      return null;
    }
    final byte[][] array = new byte[byteArray.length][];
    for (int i = 0; i < byteArray.length; i++) {
      array[i] = new byte[byteArray[i].length];
      for (int j = 0; j < byteArray[i].length; j++) {
        array[i][j] = byteArray[i][j];
      }
    }
    return array;
  }
}
