/*
 * 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.calcite.avatica.util;

import org.apache.calcite.avatica.AvaticaUtils;
import org.apache.calcite.avatica.ColumnMetaData;

import java.sql.Array;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Types;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Objects;

/** Implementation of JDBC {@link Array}. */
public class ArrayImpl implements Array {
  private final List<Object> list;
  private final AbstractCursor.ArrayAccessor accessor;

  public ArrayImpl(List<Object> list, AbstractCursor.ArrayAccessor accessor) {
    this.list = list;
    this.accessor = accessor;
  }

  public String getBaseTypeName() throws SQLException {
    return accessor.componentType.getName();
  }

  public int getBaseType() throws SQLException {
    return accessor.componentType.id;
  }

  public Object getArray() throws SQLException {
    return getArray(list, accessor);
  }

  @Override public String toString() {
    final Iterator<?> iterator = list.iterator();
    if (!iterator.hasNext()) {
      return "[]";
    }
    final StringBuilder buf = new StringBuilder("[");
    for (;;) {
      accessor.componentSlotGetter.slot = iterator.next();
      try {
        append(buf, accessor.componentAccessor.getString());
      } catch (SQLException e) {
        throw new RuntimeException(e);
      }
      accessor.componentSlotGetter.slot = null;
      if (!iterator.hasNext()) {
        return buf.append("]").toString();
      }
      buf.append(", ");
    }
  }

  private void append(StringBuilder buf, Object o) {
    if (o == null) {
      buf.append("null");
    } else if (o.getClass().isArray()) {
      append(buf, AvaticaUtils.primitiveList(o));
    } else {
      buf.append(o);
    }
  }

  /**
   * Converts a list into an array.
   *
   * <p>If the elements of the list are primitives, converts to an array of
   * primitives (e.g. {@code boolean[]}.</p>
   *
   * @param list List of objects
   *
   * @return array
   * @throws ClassCastException   if any element is not of the box type
   * @throws NullPointerException if any element is null
   */
  @SuppressWarnings("unchecked")
  protected Object getArray(List<?> list, AbstractCursor.ArrayAccessor arrayAccessor)
      throws SQLException {
    int i = 0;
    switch (arrayAccessor.componentType.rep) {
    case PRIMITIVE_DOUBLE:
      final double[] doubles = new double[list.size()];
      for (double v : (List<Double>) list) {
        doubles[i++] = v;
      }
      return doubles;
    case PRIMITIVE_FLOAT:
      final float[] floats = new float[list.size()];
      for (float v : (List<Float>) list) {
        floats[i++] = v;
      }
      return floats;
    case PRIMITIVE_INT:
      final int[] ints = new int[list.size()];
      for (int v : (List<Integer>) list) {
        ints[i++] = v;
      }
      return ints;
    case PRIMITIVE_LONG:
      final long[] longs = new long[list.size()];
      for (long v : (List<Long>) list) {
        longs[i++] = v;
      }
      return longs;
    case PRIMITIVE_SHORT:
      final short[] shorts = new short[list.size()];
      for (short v : (List<Short>) list) {
        shorts[i++] = v;
      }
      return shorts;
    case PRIMITIVE_BOOLEAN:
      final boolean[] booleans = new boolean[list.size()];
      for (boolean v : (List<Boolean>) list) {
        booleans[i++] = v;
      }
      return booleans;
    case PRIMITIVE_BYTE:
      final byte[] bytes = new byte[list.size()];
      for (byte v : (List<Byte>) list) {
        bytes[i++] = v;
      }
      return bytes;
    case PRIMITIVE_CHAR:
      final char[] chars = new char[list.size()];
      for (char v : (List<Character>) list) {
        chars[i++] = v;
      }
      return chars;
    default:
      // fall through
    }
    final Object[] objects = list.toArray();
    switch (arrayAccessor.componentType.id) {
    case Types.ARRAY:
      final AbstractCursor.ArrayAccessor componentAccessor =
          (AbstractCursor.ArrayAccessor) arrayAccessor.componentAccessor;
      for (i = 0; i < objects.length; i++) {
        // Convert the element into a Object[] or primitive array, recurse!
        objects[i] = getArrayData(objects[i], componentAccessor);
      }
    }
    return objects;
  }

  Object getArrayData(Object o, AbstractCursor.ArrayAccessor componentAccessor)
      throws SQLException {
    if (o instanceof List) {
      return getArray((List<?>) o, componentAccessor);
    } else if (o instanceof ArrayImpl) {
      return (ArrayImpl) o;
    }
    throw new RuntimeException("Unhandled");
  }

  @Override public Object getArray(Map<String, Class<?>> map) throws SQLException {
    throw new UnsupportedOperationException(); // TODO
  }

  @Override public Object getArray(long index, int count) throws SQLException {
    if (index > Integer.MAX_VALUE) {
      throw new IllegalArgumentException("Arrays cannot be longer than " + Integer.MAX_VALUE);
    }
    // Convert from one-index to zero-index
    int startIndex = ((int) index) - 1;
    if (startIndex < 0 || startIndex > list.size()) {
      throw new IllegalArgumentException("Invalid index: " + index + ". Size = " + list.size());
    }
    int endIndex = startIndex + count;
    if (endIndex > list.size()) {
      throw new IllegalArgumentException("Invalid count provided. Size = " + list.size()
          + ", count = " + count);
    }
    // End index is non-inclusive
    return getArray(list.subList(startIndex, endIndex), accessor);
  }

  @Override public Object getArray(long index, int count, Map<String, Class<?>> map)
      throws SQLException {
    throw new UnsupportedOperationException(); // TODO
  }

  @Override public ResultSet getResultSet() throws SQLException {
    return accessor.factory.create(accessor.componentType, list);
  }

  @Override public ResultSet getResultSet(Map<String, Class<?>> map)
      throws SQLException {
    throw new UnsupportedOperationException(); // TODO
  }

  @Override public ResultSet getResultSet(long index, int count) throws SQLException {
    throw new UnsupportedOperationException(); // TODO
  }

  @Override public ResultSet getResultSet(long index, int count,
      Map<String, Class<?>> map) throws SQLException {
    throw new UnsupportedOperationException(); // TODO
  }

  @Override public void free() throws SQLException {
    // nothing to do
  }

  /** Returns whether two arrays have the same contents.
   *
   * <p>Arrays must have the same size, and elements in the same order.
   * Elements are compared using {@link Object#equals(Object)}, and null
   * values are equal to each other. */
  public static boolean equalContents(Array left, Array right) throws SQLException {
    if (left.getBaseType() != right.getBaseType()) {
      return false;
    }
    ResultSet leftResultSet = left.getResultSet();
    ResultSet rightResultSet = right.getResultSet();
    int leftColumnCount = leftResultSet.getMetaData().getColumnCount();
    int rightColumnCount = rightResultSet.getMetaData().getColumnCount();
    if (leftColumnCount != rightColumnCount) {
      return false;
    }
    while (leftResultSet.next() && rightResultSet.next()) {
      for (int i = 1; i <= leftColumnCount; i++) {
        if (!Objects.equals(leftResultSet.getObject(i), rightResultSet.getObject(i))) {
          return false;
        }
      }
    }
    return !leftResultSet.next() && !rightResultSet.next();
  }

  /** Factory that can create a ResultSet or Array based on a stream of values. */
  public interface Factory {

    /**
     * Creates a {@link ResultSet} from the given list of values per {@link Array#getResultSet()}.
     *
     * @param elementType The type of the elements
     * @param iterable The elements
     * @throws SQLException on error
     */
    ResultSet create(ColumnMetaData.AvaticaType elementType, Iterable<Object> iterable)
        throws SQLException;

    /**
     * Creates an {@link Array} from the given list of values, converting any primitive values
     * into the corresponding objects.
     *
     * @param elementType The type of the elements
     * @param elements The elements
     */
    Array createArray(ColumnMetaData.AvaticaType elementType, Iterable<Object> elements);
  }
}

// End ArrayImpl.java
