/*
 * 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.AvaticaSite;
import org.apache.calcite.avatica.AvaticaUtils;
import org.apache.calcite.avatica.ColumnMetaData;

import java.io.InputStream;
import java.io.Reader;
import java.lang.reflect.Field;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.net.URL;
import java.nio.charset.StandardCharsets;
import java.sql.Array;
import java.sql.Blob;
import java.sql.Clob;
import java.sql.Date;
import java.sql.NClob;
import java.sql.Ref;
import java.sql.SQLDataException;
import java.sql.SQLException;
import java.sql.SQLXML;
import java.sql.Struct;
import java.sql.Time;
import java.sql.Timestamp;
import java.sql.Types;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.List;
import java.util.Map;

/**
 * Base class for implementing a cursor.
 *
 * <p>Derived class needs to provide {@link Getter} and can override
 * {@link org.apache.calcite.avatica.util.Cursor.Accessor} implementations if it
 * wishes.</p>
 */
public abstract class AbstractCursor implements Cursor {
  /**
   * Slot into which each accessor should write whether the
   * value returned was null.
   */
  protected final boolean[] wasNull = {false};

  protected AbstractCursor() {
  }

  public boolean wasNull() {
    return wasNull[0];
  }

  public List<Accessor> createAccessors(List<ColumnMetaData> types,
      Calendar localCalendar, ArrayImpl.Factory factory) {
    List<Accessor> accessors = new ArrayList<>();
    for (ColumnMetaData type : types) {
      accessors.add(
          createAccessor(type, accessors.size(), localCalendar, factory));
    }
    return accessors;
  }

  protected Accessor createAccessor(ColumnMetaData columnMetaData, int ordinal,
      Calendar localCalendar, ArrayImpl.Factory factory) {
    // Create an accessor appropriate to the underlying type; the accessor
    // can convert to any type in the same family.
    Getter getter = createGetter(ordinal);
    return createAccessor(columnMetaData, getter, localCalendar, factory);
  }

  protected Accessor createAccessor(ColumnMetaData columnMetaData,
      Getter getter, Calendar localCalendar, ArrayImpl.Factory factory) {
    switch (columnMetaData.type.rep) {
    case NUMBER:
      switch (columnMetaData.type.id) {
      case Types.TINYINT:
      case Types.SMALLINT:
      case Types.INTEGER:
      case Types.BIGINT:
      case Types.REAL:
      case Types.FLOAT:
      case Types.DOUBLE:
      case Types.NUMERIC:
      case Types.DECIMAL:
        return new NumberAccessor(getter, columnMetaData.scale);
      }
    }
    switch (columnMetaData.type.id) {
    case Types.TINYINT:
      return new ByteAccessor(getter);
    case Types.SMALLINT:
      return new ShortAccessor(getter);
    case Types.INTEGER:
      return new IntAccessor(getter);
    case Types.BIGINT:
      return new LongAccessor(getter);
    case Types.BOOLEAN:
    case Types.BIT:
      return new BooleanAccessor(getter);
    case Types.REAL:
      return new FloatAccessor(getter);
    case Types.FLOAT:
    case Types.DOUBLE:
      return new DoubleAccessor(getter);
    case Types.DECIMAL:
      return new NumberAccessor(getter, columnMetaData.scale);
    case Types.CHAR:
      switch (columnMetaData.type.rep) {
      case PRIMITIVE_CHAR:
      case CHARACTER:
        return new StringFromCharAccessor(getter, columnMetaData.displaySize);
      default:
        return new FixedStringAccessor(getter, columnMetaData.displaySize);
      }
    case Types.VARCHAR:
      return new StringAccessor(getter);
    case Types.BINARY:
    case Types.VARBINARY:
      switch (columnMetaData.type.rep) {
      case STRING:
        return new BinaryFromStringAccessor(getter);
      default:
        return new BinaryAccessor(getter);
      }
    case Types.DATE:
      switch (columnMetaData.type.rep) {
      case PRIMITIVE_INT:
      case INTEGER:
      case NUMBER:
        return new DateFromNumberAccessor(getter, localCalendar);
      case JAVA_SQL_DATE:
        return new DateAccessor(getter);
      default:
        throw new AssertionError("bad " + columnMetaData.type.rep);
      }
    case Types.TIME:
      switch (columnMetaData.type.rep) {
      case PRIMITIVE_INT:
      case INTEGER:
      case NUMBER:
        return new TimeFromNumberAccessor(getter, localCalendar);
      case JAVA_SQL_TIME:
        return new TimeAccessor(getter);
      default:
        throw new AssertionError("bad " + columnMetaData.type.rep);
      }
    case Types.TIMESTAMP:
      switch (columnMetaData.type.rep) {
      case PRIMITIVE_LONG:
      case LONG:
      case NUMBER:
        return new TimestampFromNumberAccessor(getter, localCalendar);
      case JAVA_SQL_TIMESTAMP:
        return new TimestampAccessor(getter);
      case JAVA_UTIL_DATE:
        return new TimestampFromUtilDateAccessor(getter, localCalendar);
      default:
        throw new AssertionError("bad " + columnMetaData.type.rep);
      }
    case 2013: // TIME_WITH_TIMEZONE
      switch (columnMetaData.type.rep) {
      case STRING:
        return new StringAccessor(getter);
      default:
        throw new AssertionError("bad " + columnMetaData.type.rep);
      }
    case 2014: // TIMESTAMP_WITH_TIMEZONE
      switch (columnMetaData.type.rep) {
      case STRING:
        return new StringAccessor(getter);
      default:
        throw new AssertionError("bad " + columnMetaData.type.rep);
      }
    case Types.ARRAY:
      final ColumnMetaData.ArrayType arrayType =
          (ColumnMetaData.ArrayType) columnMetaData.type;
      final SlotGetter componentGetter = new SlotGetter();
      final Accessor componentAccessor =
          createAccessor(ColumnMetaData.dummy(arrayType.getComponent(), true),
              componentGetter, localCalendar, factory);
      return new ArrayAccessor(getter, arrayType.getComponent(), componentAccessor,
          componentGetter, factory);
    case Types.STRUCT:
      switch (columnMetaData.type.rep) {
      case OBJECT:
        final ColumnMetaData.StructType structType =
            (ColumnMetaData.StructType) columnMetaData.type;
        List<Accessor> accessors = new ArrayList<>();
        for (ColumnMetaData column : structType.columns) {
          accessors.add(
              createAccessor(column, new StructGetter(getter, column), localCalendar, factory));
        }
        return new StructAccessor(getter, accessors);
      default:
        throw new AssertionError("bad " + columnMetaData.type.rep);
      }
    case Types.JAVA_OBJECT:
    case Types.NULL:
    case Types.OTHER: // e.g. map
      if (columnMetaData.type.getName().startsWith("INTERVAL_")) {
        int end = columnMetaData.type.getName().indexOf("(");
        if (end < 0) {
          end = columnMetaData.type.getName().length();
        }
        TimeUnitRange range =
            TimeUnitRange.valueOf(
                columnMetaData.type.getName().substring("INTERVAL_".length(), end));
        if (range.monthly()) {
          return new IntervalYearMonthAccessor(getter, range);
        } else {
          return new IntervalDayTimeAccessor(getter, range,
              columnMetaData.scale);
        }
      }
      return new ObjectAccessor(getter);
    default:
      throw new RuntimeException("unknown type " + columnMetaData.type.id);
    }
  }

  protected abstract Getter createGetter(int ordinal);

  public abstract boolean next();

  /** Accesses a timestamp value as a string.
   * The timestamp is in SQL format (e.g. "2013-09-22 22:30:32"),
   * not Java format ("2013-09-22 22:30:32.123"). */
  private static String timestampAsString(long v, Calendar calendar) {
    if (calendar != null) {
      v -= calendar.getTimeZone().getOffset(v);
    }
    return DateTimeUtils.unixTimestampToString(v);
  }

  /** Accesses a date value as a string, e.g. "2013-09-22". */
  private static String dateAsString(int v, Calendar calendar) {
    AvaticaUtils.discard(calendar); // time zone shift doesn't make sense
    return DateTimeUtils.unixDateToString(v);
  }

  /** Accesses a time value as a string, e.g. "22:30:32". */
  private static String timeAsString(int v, Calendar calendar) {
    if (calendar != null) {
      v -= calendar.getTimeZone().getOffset(v);
    }
    return DateTimeUtils.unixTimeToString(v);
  }

  private static Date longToDate(long v, Calendar calendar) {
    if (calendar != null) {
      v -= calendar.getTimeZone().getOffset(v);
    }
    return new Date(v);
  }

  static Time intToTime(int v, Calendar calendar) {
    if (calendar != null) {
      v -= calendar.getTimeZone().getOffset(v);
    }
    return new Time(v);
  }

  static Timestamp longToTimestamp(long v, Calendar calendar) {
    if (calendar != null) {
      v -= calendar.getTimeZone().getOffset(v);
    }
    return new Timestamp(v);
  }

  /** Implementation of {@link Cursor.Accessor}. */
  static class AccessorImpl implements Accessor {
    protected final Getter getter;

    AccessorImpl(Getter getter) {
      assert getter != null;
      this.getter = getter;
    }

    public boolean wasNull() throws SQLException {
      return getter.wasNull();
    }

    public String getString() throws SQLException {
      final Object o = getObject();
      return o == null ? null : o.toString();
    }

    public boolean getBoolean() throws SQLException {
      return getLong() != 0L;
    }

    public byte getByte() throws SQLException {
      return (byte) getLong();
    }

    public short getShort() throws SQLException {
      return (short) getLong();
    }

    public int getInt() throws SQLException {
      return (int) getLong();
    }

    public long getLong() throws SQLException {
      throw cannotConvert("long");
    }

    public float getFloat() throws SQLException {
      return (float) getDouble();
    }

    public double getDouble() throws SQLException {
      throw cannotConvert("double");
    }

    public BigDecimal getBigDecimal() throws SQLException {
      throw cannotConvert("BigDecimal");
    }

    public BigDecimal getBigDecimal(int scale) throws SQLException {
      throw cannotConvert("BigDecimal with scale");
    }

    public byte[] getBytes() throws SQLException {
      throw cannotConvert("byte[]");
    }

    public InputStream getAsciiStream() throws SQLException {
      throw cannotConvert("InputStream (ascii)");
    }

    public InputStream getUnicodeStream() throws SQLException {
      throw cannotConvert("InputStream (unicode)");
    }

    public InputStream getBinaryStream() throws SQLException {
      throw cannotConvert("InputStream (binary)");
    }

    public Object getObject() throws SQLException {
      return getter.getObject();
    }

    public Reader getCharacterStream() throws SQLException {
      throw cannotConvert("Reader");
    }

    private SQLException cannotConvert(String targetType) throws SQLException {
      return new SQLDataException("cannot convert to " + targetType + " ("
          + this + ")");
    }

    public Object getObject(Map<String, Class<?>> map) throws SQLException {
      throw cannotConvert("Object (with map)");
    }

    public Ref getRef() throws SQLException {
      throw cannotConvert("Ref");
    }

    public Blob getBlob() throws SQLException {
      throw cannotConvert("Blob");
    }

    public Clob getClob() throws SQLException {
      throw cannotConvert("Clob");
    }

    public Array getArray() throws SQLException {
      throw cannotConvert("Array");
    }

    public Struct getStruct() throws SQLException {
      throw cannotConvert("Struct");
    }

    public Date getDate(Calendar calendar) throws SQLException {
      throw cannotConvert("Date");
    }

    public Time getTime(Calendar calendar) throws SQLException {
      throw cannotConvert("Time");
    }

    public Timestamp getTimestamp(Calendar calendar) throws SQLException {
      throw cannotConvert("Timestamp");
    }

    public URL getURL() throws SQLException {
      throw cannotConvert("URL");
    }

    public NClob getNClob() throws SQLException {
      throw cannotConvert("NClob");
    }

    public SQLXML getSQLXML() throws SQLException {
      throw cannotConvert("SQLXML");
    }

    public String getNString() throws SQLException {
      throw cannotConvert("NString");
    }

    public Reader getNCharacterStream() throws SQLException {
      throw cannotConvert("NCharacterStream");
    }

    public <T> T getObject(Class<T> type) throws SQLException {
      throw cannotConvert("Object (with type)");
    }
  }

  /**
   * Accessor of exact numeric values. The subclass must implement the
   * {@link #getLong()} method.
   */
  private abstract static class ExactNumericAccessor extends AccessorImpl {
    private ExactNumericAccessor(Getter getter) {
      super(getter);
    }

    public BigDecimal getBigDecimal(int scale) throws SQLException {
      final long v = getLong();
      if (v == 0 && getter.wasNull()) {
        return null;
      }
      return BigDecimal.valueOf(v).setScale(scale, RoundingMode.DOWN);
    }

    public BigDecimal getBigDecimal() throws SQLException {
      final long val = getLong();
      if (val == 0 && getter.wasNull()) {
        return null;
      }
      return BigDecimal.valueOf(val);
    }

    public double getDouble() throws SQLException {
      return getLong();
    }

    public float getFloat() throws SQLException {
      return getLong();
    }

    public abstract long getLong() throws SQLException;
  }

  /**
   * Accessor that assumes that the underlying value is a {@link Boolean};
   * corresponds to {@link java.sql.Types#BOOLEAN}.
   */
  private static class BooleanAccessor extends ExactNumericAccessor {
    private BooleanAccessor(Getter getter) {
      super(getter);
    }

    public boolean getBoolean() throws SQLException {
      Boolean o = (Boolean) getObject();
      return o != null && o;
    }

    public long getLong() throws SQLException {
      return getBoolean() ? 1 : 0;
    }
  }

  /**
   * Accessor that assumes that the underlying value is a {@link Byte};
   * corresponds to {@link java.sql.Types#TINYINT}.
   */
  private static class ByteAccessor extends ExactNumericAccessor {
    private ByteAccessor(Getter getter) {
      super(getter);
    }

    public byte getByte() throws SQLException {
      Object obj = getObject();
      if (null == obj) {
        return 0;
      } else if (obj instanceof Integer) {
        return ((Integer) obj).byteValue();
      }
      return (Byte) obj;
    }

    public long getLong() throws SQLException {
      return getByte();
    }
  }

  /**
   * Accessor that assumes that the underlying value is a {@link Short};
   * corresponds to {@link java.sql.Types#SMALLINT}.
   */
  private static class ShortAccessor extends ExactNumericAccessor {
    private ShortAccessor(Getter getter) {
      super(getter);
    }

    public short getShort() throws SQLException {
      Object obj = getObject();
      if (null == obj) {
        return 0;
      } else if (obj instanceof Integer) {
        return ((Integer) obj).shortValue();
      }
      return (Short) obj;
    }

    public long getLong() throws SQLException {
      return getShort();
    }
  }

  /**
   * Accessor that assumes that the underlying value is an {@link Integer};
   * corresponds to {@link java.sql.Types#INTEGER}.
   */
  private static class IntAccessor extends ExactNumericAccessor {
    private IntAccessor(Getter getter) {
      super(getter);
    }

    public int getInt() throws SQLException {
      Integer o = (Integer) super.getObject();
      return o == null ? 0 : o;
    }

    public long getLong() throws SQLException {
      return getInt();
    }
  }

  /**
   * Accessor that assumes that the underlying value is a {@link Long};
   * corresponds to {@link java.sql.Types#BIGINT}.
   */
  private static class LongAccessor extends ExactNumericAccessor {
    private LongAccessor(Getter getter) {
      super(getter);
    }

    public long getLong() throws SQLException {
      Long o = (Long) super.getObject();
      return o == null ? 0 : o;
    }
  }

  /**
   * Accessor of values that are {@link Double} or null.
   */
  private abstract static class ApproximateNumericAccessor
      extends AccessorImpl {
    private ApproximateNumericAccessor(Getter getter) {
      super(getter);
    }

    public BigDecimal getBigDecimal(int scale) throws SQLException {
      final double v = getDouble();
      if (v == 0d && getter.wasNull()) {
        return null;
      }
      return BigDecimal.valueOf(v).setScale(scale, RoundingMode.DOWN);
    }

    public BigDecimal getBigDecimal() throws SQLException {
      final double v = getDouble();
      if (v == 0 && getter.wasNull()) {
        return null;
      }
      return BigDecimal.valueOf(v);
    }

    public abstract double getDouble() throws SQLException;

    public long getLong() throws SQLException {
      return (long) getDouble();
    }
  }

  /**
   * Accessor that assumes that the underlying value is a {@link Float};
   * corresponds to {@link java.sql.Types#FLOAT}.
   */
  private static class FloatAccessor extends ApproximateNumericAccessor {
    private FloatAccessor(Getter getter) {
      super(getter);
    }

    public float getFloat() throws SQLException {
      Float o = (Float) getObject();
      return o == null ? 0f : o;
    }

    public double getDouble() throws SQLException {
      return getFloat();
    }
  }

  /**
   * Accessor that assumes that the underlying value is a {@link Double};
   * corresponds to {@link java.sql.Types#DOUBLE}.
   */
  private static class DoubleAccessor extends ApproximateNumericAccessor {
    private DoubleAccessor(Getter getter) {
      super(getter);
    }

    public double getDouble() throws SQLException {
      Object obj = getObject();
      if (null == obj) {
        return 0d;
      } else if (obj instanceof BigDecimal) {
        return ((BigDecimal) obj).doubleValue();
      }
      return (Double) obj;
    }
  }

  /**
   * Accessor of exact numeric values. The subclass must implement the
   * {@link #getLong()} method.
   */
  private abstract static class BigNumberAccessor extends AccessorImpl {
    private BigNumberAccessor(Getter getter) {
      super(getter);
    }

    protected abstract Number getNumber() throws SQLException;

    public double getDouble() throws SQLException {
      Number number = getNumber();
      return number == null ? 0d : number.doubleValue();
    }

    public float getFloat() throws SQLException {
      Number number = getNumber();
      return number == null ? 0f : number.floatValue();
    }

    public long getLong() throws SQLException {
      Number number = getNumber();
      return number == null ? 0L : number.longValue();
    }

    public int getInt() throws SQLException {
      Number number = getNumber();
      return number == null ? 0 : number.intValue();
    }

    public short getShort() throws SQLException {
      Number number = getNumber();
      return number == null ? 0 : number.shortValue();
    }

    public byte getByte() throws SQLException {
      Number number = getNumber();
      return number == null ? 0 : number.byteValue();
    }

    public boolean getBoolean() throws SQLException {
      Number number = getNumber();
      return number != null && number.doubleValue() != 0;
    }
  }

  /**
   * Accessor that assumes that the underlying value is a {@link Number};
   * corresponds to {@link java.sql.Types#NUMERIC}
   * or {@link java.sql.Types#DECIMAL}.
   *
   * <p>This is useful when numbers have been translated over JSON. JSON
   * converts a 0L (0 long) value to the string "0" and back to 0 (0 int).
   * So you cannot be sure that the source and target type are the same.
   */
  static class NumberAccessor extends BigNumberAccessor {
    private final int scale;

    NumberAccessor(Getter getter, int scale) {
      super(getter);
      this.scale = scale;
    }

    protected Number getNumber() throws SQLException {
      return (Number) super.getObject();
    }

    //FIXME There are several issues with this, the code below simply implements
    //a previous behaviour codified by the Calcite test suite.
    //
    // 1. It interprets a scale of 0 as a NOOP parameter, it should in fact drop all fractionals
    // 2. The scale from MetaData is NOT applied to BigDecimal values. Why ?
    // 3. Metadata scale is only applied for getBigDecimal(), and only in this Accessor. Why ?
    public BigDecimal getBigDecimal(int scale) throws SQLException {
      Number n = getNumber();
      if (n == null) {
        return null;
      }
      BigDecimal decimal = AvaticaSite.toBigDecimal(n);
      if (0 != scale && !(n instanceof BigDecimal)) {
        return decimal.setScale(scale, RoundingMode.DOWN);
      }
      return decimal;
    }

    public BigDecimal getBigDecimal() throws SQLException {
      return getBigDecimal(scale);
    }

  }

  /**
   * Accessor that assumes that the underlying value is a {@link String};
   * corresponds to {@link java.sql.Types#CHAR}
   * and {@link java.sql.Types#VARCHAR}.
   */
  private static class StringAccessor extends AccessorImpl {
    private StringAccessor(Getter getter) {
      super(getter);
    }

    public String getString() throws SQLException {
      final Object obj = getObject();
      if (obj instanceof String) {
        return (String) obj;
      }
      return null == obj ? null : obj.toString();
    }

    @Override public byte[] getBytes() throws SQLException {
      return super.getBytes();
    }
  }

  /**
   * Accessor that assumes that the underlying value is a {@link String};
   * corresponds to {@link java.sql.Types#CHAR}.
   */
  private static class FixedStringAccessor extends StringAccessor {
    protected final Spacer spacer;

    private FixedStringAccessor(Getter getter, int length) {
      super(getter);
      this.spacer = new Spacer(length);
    }

    public String getString() throws SQLException {
      String s = super.getString();
      if (s == null) {
        return null;
      }
      return spacer.padRight(s);
    }
  }

  /**
   * Accessor that assumes that the underlying value is a {@link String};
   * corresponds to {@link java.sql.Types#CHAR}.
   */
  private static class StringFromCharAccessor extends FixedStringAccessor {
    private StringFromCharAccessor(Getter getter, int length) {
      super(getter, length);
    }

    public String getString() throws SQLException {
      Character s = (Character) super.getObject();
      if (s == null) {
        return null;
      }
      return spacer.padRight(s.toString());
    }
  }

  /**
   * Accessor that assumes that the underlying value is an array of
   * {@link org.apache.calcite.avatica.util.ByteString} values;
   * corresponds to {@link java.sql.Types#BINARY}
   * and {@link java.sql.Types#VARBINARY}.
   */
  private static class BinaryAccessor extends AccessorImpl {
    private BinaryAccessor(Getter getter) {
      super(getter);
    }

    //FIXME: Protobuf gets byte[]
    @Override public byte[] getBytes() throws SQLException {
      Object obj = getObject();
      if (null == obj) {
        return null;
      }
      if (obj instanceof ByteString) {
        return ((ByteString) obj).getBytes();
      } else if (obj instanceof String) {
        // Need to unwind the base64 for JSON
        return ByteString.parseBase64((String) obj);
      } else if (obj instanceof byte[]) {
        // Protobuf would have a byte array
        return (byte[]) obj;
      } else {
        throw new RuntimeException("Cannot handle " + obj.getClass() + " as bytes");
      }
    }

    @Override public String getString() throws SQLException {
      Object o = getObject();
      if (null == o) {
        return null;
      }
      if (o instanceof byte[]) {
        return new String((byte[]) o, StandardCharsets.UTF_8);
      } else if (o instanceof ByteString) {
        return ((ByteString) o).toString();
      }
      throw new IllegalStateException("Unhandled value type: " + o.getClass());
    }
  }

  /**
   * Accessor that assumes that the underlying value is a {@link String},
   * encoding {@link java.sql.Types#BINARY}
   * and {@link java.sql.Types#VARBINARY} values in Base64 format.
   */
  private static class BinaryFromStringAccessor extends StringAccessor {
    private BinaryFromStringAccessor(Getter getter) {
      super(getter);
    }

    @Override public Object getObject() throws SQLException {
      return super.getObject();
    }

    @Override public byte[] getBytes() throws SQLException {
      // JSON sends this as a base64-enc string, protobuf can do binary.
      Object obj = getObject();

      if (obj instanceof byte[]) {
        // If we already have bytes, just send them back.
        return (byte[]) obj;
      }

      return getBase64Decoded();
    }

    private byte[] getBase64Decoded() throws SQLException {
      final String string = super.getString();
      if (null == string) {
        return null;
      }
      // Need to base64 decode the string.
      return ByteString.parseBase64(string);
    }

    @Override public String getString() throws SQLException {
      final byte[] bytes = getBase64Decoded();
      if (null == bytes) {
        return null;
      }
      // Need to base64 decode the string.
      return new String(bytes, StandardCharsets.UTF_8);
    }
  }

  /**
   * Accessor that assumes that the underlying value is a DATE,
   * in its default representation {@code int};
   * corresponds to {@link java.sql.Types#DATE}.
   */
  private static class DateFromNumberAccessor extends NumberAccessor {
    private final Calendar localCalendar;

    private DateFromNumberAccessor(Getter getter, Calendar localCalendar) {
      super(getter, 0);
      this.localCalendar = localCalendar;
    }

    @Override public Object getObject() throws SQLException {
      return getDate(localCalendar);
    }

    @Override public Date getDate(Calendar calendar) throws SQLException {
      final Number v = getNumber();
      if (v == null) {
        return null;
      }
      return longToDate(v.longValue() * DateTimeUtils.MILLIS_PER_DAY, calendar);
    }

    @Override public Timestamp getTimestamp(Calendar calendar) throws SQLException {
      final Number v = getNumber();
      if (v == null) {
        return null;
      }
      return longToTimestamp(v.longValue() * DateTimeUtils.MILLIS_PER_DAY,
          calendar);
    }

    @Override public String getString() throws SQLException {
      final Number v = getNumber();
      if (v == null) {
        return null;
      }
      return dateAsString(v.intValue(), null);
    }
  }

  /**
   * Accessor that assumes that the underlying value is a Time,
   * in its default representation {@code int};
   * corresponds to {@link java.sql.Types#TIME}.
   */
  private static class TimeFromNumberAccessor extends NumberAccessor {
    private final Calendar localCalendar;

    private TimeFromNumberAccessor(Getter getter, Calendar localCalendar) {
      super(getter, 0);
      this.localCalendar = localCalendar;
    }

    @Override public Object getObject() throws SQLException {
      return getTime(localCalendar);
    }

    @Override public Time getTime(Calendar calendar) throws SQLException {
      final Number v = getNumber();
      if (v == null) {
        return null;
      }
      return intToTime(v.intValue(), calendar);
    }

    @Override public Timestamp getTimestamp(Calendar calendar) throws SQLException {
      final Number v = getNumber();
      if (v == null) {
        return null;
      }
      return longToTimestamp(v.longValue(), calendar);
    }

    @Override public String getString() throws SQLException {
      final Number v = getNumber();
      if (v == null) {
        return null;
      }
      return timeAsString(v.intValue(), null);
    }
  }

  /**
   * Accessor that assumes that the underlying value is a TIMESTAMP,
   * in its default representation {@code long};
   * corresponds to {@link java.sql.Types#TIMESTAMP}.
   */
  private static class TimestampFromNumberAccessor extends NumberAccessor {
    private final Calendar localCalendar;

    private TimestampFromNumberAccessor(Getter getter, Calendar localCalendar) {
      super(getter, 0);
      this.localCalendar = localCalendar;
    }

    @Override public Object getObject() throws SQLException {
      return getTimestamp(localCalendar);
    }

    @Override public Timestamp getTimestamp(Calendar calendar) throws SQLException {
      final Number v = getNumber();
      if (v == null) {
        return null;
      }
      return longToTimestamp(v.longValue(), calendar);
    }

    @Override public Date getDate(Calendar calendar) throws SQLException {
      final Timestamp timestamp  = getTimestamp(calendar);
      if (timestamp == null) {
        return null;
      }
      return new Date(timestamp.getTime());
    }

    @Override public Time getTime(Calendar calendar) throws SQLException {
      final Timestamp timestamp  = getTimestamp(calendar);
      if (timestamp == null) {
        return null;
      }
      return new Time(
          DateTimeUtils.floorMod(timestamp.getTime(),
              DateTimeUtils.MILLIS_PER_DAY));
    }

    @Override public String getString() throws SQLException {
      final Number v = getNumber();
      if (v == null) {
        return null;
      }
      return timestampAsString(v.longValue(), null);
    }
  }

  /**
   * Accessor that assumes that the underlying value is a DATE,
   * represented as a java.sql.Date;
   * corresponds to {@link java.sql.Types#DATE}.
   */
  private static class DateAccessor extends ObjectAccessor {
    private DateAccessor(Getter getter) {
      super(getter);
    }

    @Override public Date getDate(Calendar calendar) throws SQLException {
      java.sql.Date date = (Date) getObject();
      if (date == null) {
        return null;
      }
      if (calendar != null) {
        long v = date.getTime();
        v -= calendar.getTimeZone().getOffset(v);
        date = new Date(v);
      }
      return date;
    }

    @Override public String getString() throws SQLException {
      final int v = getInt();
      if (v == 0 && wasNull()) {
        return null;
      }
      return dateAsString(v, null);
    }

    @Override public long getLong() throws SQLException {
      Date date = getDate(null);
      return date == null
          ? 0L
          : (date.getTime() / DateTimeUtils.MILLIS_PER_DAY);
    }
  }

  /**
   * Accessor that assumes that the underlying value is a TIME,
   * represented as a java.sql.Time;
   * corresponds to {@link java.sql.Types#TIME}.
   */
  private static class TimeAccessor extends ObjectAccessor {
    private TimeAccessor(Getter getter) {
      super(getter);
    }

    @Override public Time getTime(Calendar calendar) throws SQLException {
      Time date  = (Time) getObject();
      if (date == null) {
        return null;
      }
      if (calendar != null) {
        long v = date.getTime();
        v -= calendar.getTimeZone().getOffset(v);
        date = new Time(v);
      }
      return date;
    }

    @Override public String getString() throws SQLException {
      final int v = getInt();
      if (v == 0 && wasNull()) {
        return null;
      }
      return timeAsString(v, null);
    }

    @Override public long getLong() throws SQLException {
      Time time = getTime(null);
      return time == null ? 0L
          : (time.getTime() % DateTimeUtils.MILLIS_PER_DAY);
    }
  }

  /**
   * Accessor that assumes that the underlying value is a TIMESTAMP,
   * represented as a java.sql.Timestamp;
   * corresponds to {@link java.sql.Types#TIMESTAMP}.
   */
  private static class TimestampAccessor extends ObjectAccessor {
    private TimestampAccessor(Getter getter) {
      super(getter);
    }

    @Override public Timestamp getTimestamp(Calendar calendar) throws SQLException {
      Timestamp timestamp  = (Timestamp) getObject();
      if (timestamp == null) {
        return null;
      }
      if (calendar != null) {
        long v = timestamp.getTime();
        v -= calendar.getTimeZone().getOffset(v);
        timestamp = new Timestamp(v);
      }
      return timestamp;
    }

    @Override public Date getDate(Calendar calendar) throws SQLException {
      final Timestamp timestamp  = getTimestamp(calendar);
      if (timestamp == null) {
        return null;
      }
      return new Date(timestamp.getTime());
    }

    @Override public Time getTime(Calendar calendar) throws SQLException {
      final Timestamp timestamp  = getTimestamp(calendar);
      if (timestamp == null) {
        return null;
      }
      return new Time(
          DateTimeUtils.floorMod(timestamp.getTime(),
              DateTimeUtils.MILLIS_PER_DAY));
    }

    @Override public String getString() throws SQLException {
      final long v = getLong();
      if (v == 0 && wasNull()) {
        return null;
      }
      return timestampAsString(v, null);
    }

    @Override public long getLong() throws SQLException {
      Timestamp timestamp = getTimestamp(null);
      return timestamp == null ? 0 : timestamp.getTime();
    }
  }

  /**
   * Accessor that assumes that the underlying value is a TIMESTAMP,
   * represented as a java.util.Date;
   * corresponds to {@link java.sql.Types#TIMESTAMP}.
   */
  private static class TimestampFromUtilDateAccessor extends ObjectAccessor {
    private final Calendar localCalendar;

    private TimestampFromUtilDateAccessor(Getter getter,
        Calendar localCalendar) {
      super(getter);
      this.localCalendar = localCalendar;
    }

    @Override public Timestamp getTimestamp(Calendar calendar) throws SQLException {
      java.util.Date date  = (java.util.Date) getObject();
      if (date == null) {
        return null;
      }
      long v = date.getTime();
      if (calendar != null) {
        v -= calendar.getTimeZone().getOffset(v);
      }
      return new Timestamp(v);
    }

    @Override public Date getDate(Calendar calendar) throws SQLException {
      final Timestamp timestamp  = getTimestamp(calendar);
      if (timestamp == null) {
        return null;
      }
      return new Date(timestamp.getTime());
    }

    @Override public Time getTime(Calendar calendar) throws SQLException {
      final Timestamp timestamp  = getTimestamp(calendar);
      if (timestamp == null) {
        return null;
      }
      return new Time(
          DateTimeUtils.floorMod(timestamp.getTime(),
              DateTimeUtils.MILLIS_PER_DAY));
    }

    @Override public String getString() throws SQLException {
      java.util.Date date  = (java.util.Date) getObject();
      if (date == null) {
        return null;
      }
      return timestampAsString(date.getTime(), null);
    }

    @Override public long getLong() throws SQLException {
      Timestamp timestamp = getTimestamp(localCalendar);
      return timestamp == null ? 0 : timestamp.getTime();
    }
  }

  /**
   * Accessor that assumes that the underlying value is a {@code int};
   * corresponds to {@link java.sql.Types#OTHER}.
   */
  private static class IntervalYearMonthAccessor extends IntAccessor {
    private final TimeUnitRange range;

    private IntervalYearMonthAccessor(Getter getter, TimeUnitRange range) {
      super(getter);
      this.range = range;
    }

    @Override public String getString() throws SQLException {
      final int v = getInt();
      if (v == 0 && wasNull()) {
        return null;
      }
      return DateTimeUtils.intervalYearMonthToString(v, range);
    }
  }

  /**
   * Accessor that assumes that the underlying value is a {@code long};
   * corresponds to {@link java.sql.Types#OTHER}.
   */
  private static class IntervalDayTimeAccessor extends LongAccessor {
    private final TimeUnitRange range;
    private final int scale;

    private IntervalDayTimeAccessor(Getter getter, TimeUnitRange range,
        int scale) {
      super(getter);
      this.range = range;
      this.scale = scale;
    }

    @Override public String getString() throws SQLException {
      final long v = getLong();
      if (v == 0 && wasNull()) {
        return null;
      }
      return DateTimeUtils.intervalDayTimeToString(v, range, scale);
    }
  }

  /**
   * Accessor that assumes that the underlying value is an ARRAY;
   * corresponds to {@link java.sql.Types#ARRAY}.
   */
  public static class ArrayAccessor extends AccessorImpl {
    final ColumnMetaData.AvaticaType componentType;
    final Accessor componentAccessor;
    final SlotGetter componentSlotGetter;
    final ArrayImpl.Factory factory;

    public ArrayAccessor(Getter getter,
        ColumnMetaData.AvaticaType componentType, Accessor componentAccessor,
        SlotGetter componentSlotGetter, ArrayImpl.Factory factory) {
      super(getter);
      this.componentType = componentType;
      this.componentAccessor = componentAccessor;
      this.componentSlotGetter = componentSlotGetter;
      this.factory = factory;
    }

    @Override public Object getObject() throws SQLException {
      final Object object = super.getObject();
      if (object == null || object instanceof ArrayImpl) {
        return object;
      } else if (object instanceof List) {
        List<?> list = (List<?>) object;
        // Run the array values through the component accessor
        List<Object> convertedValues = new ArrayList<>(list.size());
        for (Object val : list) {
          if (null == val) {
            convertedValues.add(null);
          } else {
            // Set the current value in the SlotGetter so we can use the Accessor to coerce it.
            componentSlotGetter.slot = val;
            convertedValues.add(convertValue());
          }
        }
        return convertedValues;
      }
      // The object can be java array in case of user-provided class for row storage.
      return AvaticaUtils.primitiveList(object);
    }

    private Object convertValue() throws SQLException {
      switch (componentType.id) {
      case Types.BOOLEAN:
      case Types.BIT:
        return componentAccessor.getBoolean();
      case Types.TINYINT:
        return componentAccessor.getByte();
      case Types.SMALLINT:
        return componentAccessor.getShort();
      case Types.INTEGER:
        return componentAccessor.getInt();
      case Types.BIGINT:
        return componentAccessor.getLong();
      case Types.REAL:
        return componentAccessor.getFloat();
      case Types.FLOAT:
      case Types.DOUBLE:
        return componentAccessor.getDouble();
      case Types.ARRAY:
        return componentAccessor.getArray();
      case Types.CHAR:
      case Types.VARCHAR:
      case Types.LONGVARCHAR:
      case Types.NCHAR:
      case Types.LONGNVARCHAR:
        return componentAccessor.getString();
      case Types.BINARY:
      case Types.VARBINARY:
      case Types.LONGVARBINARY:
        return componentAccessor.getBytes();
      case Types.DECIMAL:
        return componentAccessor.getBigDecimal();
      case Types.DATE:
      case Types.TIME:
      case Types.TIMESTAMP:
      case Types.STRUCT:
      case Types.JAVA_OBJECT:
      case Types.OTHER:
        return componentAccessor.getObject();
      default:
        throw new IllegalStateException("Unhandled ARRAY component type: " + componentType.rep
            + ", id: " + componentType.id);
      }
    }

    @SuppressWarnings("unchecked") @Override public Array getArray() throws SQLException {
      final Object o = getObject();
      if (o == null) {
        return null;
      }
      if (o instanceof ArrayImpl) {
        return (ArrayImpl) o;
      }
      // If it's not an Array already, assume it is a List.
      return new ArrayImpl((List<Object>) o, this);
    }

    @Override public String getString() throws SQLException {
      final Array array = getArray();
      return array == null ? null : array.toString();
    }
  }

  /**
   * Accessor that assumes that the underlying value is a STRUCT;
   * corresponds to {@link java.sql.Types#STRUCT}.
   */
  private static class StructAccessor extends AccessorImpl {
    private final List<Accessor> fieldAccessors;

    private StructAccessor(Getter getter, List<Accessor> fieldAccessors) {
      super(getter);
      this.fieldAccessors = fieldAccessors;
    }

    @Override public Object getObject() throws SQLException {
      return getStruct();
    }

    @SuppressWarnings("unchecked")
    @Override public <T> T getObject(Class<T> clz) throws SQLException {
      // getStruct() is not exposed on Accessor, only AccessorImpl. getObject(Class) is exposed,
      // so we can make it do the right thing (call getStruct()).
      if (clz.equals(Struct.class)) {
        return (T) getStruct();
      }
      return super.getObject(clz);
    }

    @Override public Struct getStruct() throws SQLException {
      final Object o = super.getObject();
      if (o == null) {
        return null;
      } else if (o instanceof StructImpl) {
        return (StructImpl) o;
      } else if (o instanceof List) {
        return new StructImpl((List) o);
      } else {
        final List<Object> list = new ArrayList<>();
        for (Accessor fieldAccessor : fieldAccessors) {
          list.add(fieldAccessor.getObject());
        }
        return new StructImpl(list);
      }
    }
  }

  /**
   * Accessor that assumes that the underlying value is an OBJECT;
   * corresponds to {@link java.sql.Types#JAVA_OBJECT}.
   */
  private static class ObjectAccessor extends AccessorImpl {
    private ObjectAccessor(Getter getter) {
      super(getter);
    }
  }

  /** Gets a value from a particular field of the current record of this
   * cursor. */
  protected interface Getter {
    Object getObject() throws SQLException;

    boolean wasNull() throws SQLException;
  }

  /** Abstract implementation of {@link Getter}. */
  protected abstract class AbstractGetter implements Getter {
    public boolean wasNull() throws SQLException {
      return wasNull[0];
    }
  }

  /** Implementation of {@link Getter} that returns the current contents of
   * a mutable slot. */
  public class SlotGetter implements Getter {
    public Object slot;

    public Object getObject() throws SQLException {
      return slot;
    }

    public boolean wasNull() throws SQLException {
      return slot == null;
    }
  }

  /** Implementation of {@link Getter} that returns the value of a given field
   * of the current contents of another getter. */
  public class StructGetter implements Getter {
    public final Getter getter;
    private final ColumnMetaData columnMetaData;

    public StructGetter(Getter getter, ColumnMetaData columnMetaData) {
      this.getter = getter;
      this.columnMetaData = columnMetaData;
    }

    public Object getObject() throws SQLException {
      try {
        final Object o = getter.getObject();
        if (o instanceof Object[]) {
          Object[] objects = (Object[]) o;
          return objects[columnMetaData.ordinal];
        }
        final Field field = o.getClass().getField(columnMetaData.label);
        return field.get(getter.getObject());
      } catch (IllegalAccessException | NoSuchFieldException e) {
        throw new SQLException(e);
      }
    }

    public boolean wasNull() throws SQLException {
      return getObject() == null;
    }
  }
}

// End AbstractCursor.java
