package org.mariadb.jdbc.client;

import java.nio.charset.StandardCharsets;
import java.sql.Date;
import java.sql.SQLDataException;
import java.sql.Time;
import java.sql.Timestamp;
import java.util.Calendar;
import org.mariadb.jdbc.Configuration;
import org.mariadb.jdbc.client.column.UuidColumn;
import org.mariadb.jdbc.client.impl.StandardReadableByteBuf;
import org.mariadb.jdbc.util.constants.ColumnFlags;

public interface ColumnDecoder extends Column {

  /**
   * Returns default class name depending on server column datatype
   *
   * @param conf configuration
   * @return default class name
   */
  String defaultClassname(Configuration conf);

  /**
   * Returns default java.sql.Types depending on server column datatype
   *
   * @param conf configuration
   * @return default java.sql.Types
   */
  int getColumnType(Configuration conf);

  /**
   * Returns server column datatype
   *
   * @param conf configuration
   * @return default server column datatype
   */
  String getColumnTypeName(Configuration conf);

  /**
   * Return decimal precision.
   *
   * @return decimal precision
   */
  default int getPrecision() {
    return (int) getColumnLength();
  }

  /**
   * Return default Object text encoded
   *
   * @param conf configuration
   * @param buf row buffer
   * @param length data length
   * @return default Object
   * @throws SQLDataException if any decoding error occurs
   */
  Object getDefaultText(final Configuration conf, final ReadableByteBuf buf, final int length)
      throws SQLDataException;

  /**
   * Return default Object binary encoded
   *
   * @param conf configuration
   * @param buf row buffer
   * @param length data length
   * @return default Object
   * @throws SQLDataException if any decoding error occurs
   */
  Object getDefaultBinary(final Configuration conf, final ReadableByteBuf buf, final int length)
      throws SQLDataException;

  /**
   * Return String text encoded value
   *
   * @param buf row buffer
   * @param length data length
   * @param cal calendar
   * @return String value
   * @throws SQLDataException if any decoding error occurs
   */
  String decodeStringText(final ReadableByteBuf buf, final int length, final Calendar cal)
      throws SQLDataException;

  /**
   * Return String binary encoded value
   *
   * @param buf row buffer
   * @param length data length
   * @param cal calendar
   * @return String value
   * @throws SQLDataException if any decoding error occurs
   */
  String decodeStringBinary(final ReadableByteBuf buf, final int length, final Calendar cal)
      throws SQLDataException;

  /**
   * Return byte text encoded value
   *
   * @param buf row buffer
   * @param length data length
   * @return byte value
   * @throws SQLDataException if any decoding error occurs
   */
  byte decodeByteText(final ReadableByteBuf buf, final int length) throws SQLDataException;

  /**
   * Return byte binary encoded value
   *
   * @param buf row buffer
   * @param length data length
   * @return byte value
   * @throws SQLDataException if any decoding error occurs
   */
  byte decodeByteBinary(final ReadableByteBuf buf, final int length) throws SQLDataException;

  /**
   * Return date text encoded value
   *
   * @param buf row buffer
   * @param length data length
   * @param cal calendar
   * @return date value
   * @throws SQLDataException if any decoding error occurs
   */
  Date decodeDateText(final ReadableByteBuf buf, final int length, Calendar cal)
      throws SQLDataException;

  /**
   * Return date binary encoded value
   *
   * @param buf row buffer
   * @param length data length
   * @param cal calendar
   * @return date value
   * @throws SQLDataException if any decoding error occurs
   */
  Date decodeDateBinary(final ReadableByteBuf buf, final int length, Calendar cal)
      throws SQLDataException;

  /**
   * Return time text encoded value
   *
   * @param buf row buffer
   * @param length data length
   * @param cal calendar
   * @return time value
   * @throws SQLDataException if any decoding error occurs
   */
  Time decodeTimeText(final ReadableByteBuf buf, final int length, Calendar cal)
      throws SQLDataException;

  /**
   * Return time binary encoded value
   *
   * @param buf row buffer
   * @param length data length
   * @param cal calendar
   * @return time value
   * @throws SQLDataException if any decoding error occurs
   */
  Time decodeTimeBinary(final ReadableByteBuf buf, final int length, Calendar cal)
      throws SQLDataException;

  /**
   * Return timestamp text encoded value
   *
   * @param buf row buffer
   * @param length data length
   * @param cal calendar
   * @return timestamp value
   * @throws SQLDataException if any decoding error occurs
   */
  Timestamp decodeTimestampText(final ReadableByteBuf buf, final int length, Calendar cal)
      throws SQLDataException;

  /**
   * Return timestamp binary encoded value
   *
   * @param buf row buffer
   * @param length data length
   * @param cal calendar
   * @return timestamp value
   * @throws SQLDataException if any decoding error occurs
   */
  Timestamp decodeTimestampBinary(final ReadableByteBuf buf, final int length, Calendar cal)
      throws SQLDataException;
  /**
   * Return boolean text encoded value
   *
   * @param buf row buffer
   * @param length data length
   * @return boolean value
   * @throws SQLDataException if any decoding error occurs
   */
  boolean decodeBooleanText(final ReadableByteBuf buf, final int length) throws SQLDataException;

  /**
   * Parse boolean binary encoded value
   *
   * @param buf row buffer
   * @param length data length
   * @return boolean value
   * @throws SQLDataException if any decoding error occurs
   */
  boolean decodeBooleanBinary(final ReadableByteBuf buf, final int length) throws SQLDataException;
  /**
   * Parse short text encoded value
   *
   * @param buf row buffer
   * @param length data length
   * @return short value
   * @throws SQLDataException if any decoding error occurs
   */
  short decodeShortText(final ReadableByteBuf buf, final int length) throws SQLDataException;
  /**
   * Parse short binary encoded value
   *
   * @param buf row buffer
   * @param length data length
   * @return short value
   * @throws SQLDataException if any decoding error occurs
   */
  short decodeShortBinary(final ReadableByteBuf buf, final int length) throws SQLDataException;
  /**
   * Parse int text encoded value
   *
   * @param buf row buffer
   * @param length data length
   * @return int value
   * @throws SQLDataException if any decoding error occurs
   */
  int decodeIntText(final ReadableByteBuf buf, final int length) throws SQLDataException;

  /**
   * Parse int binary encoded value
   *
   * @param buf row buffer
   * @param length data length
   * @return int value
   * @throws SQLDataException if any decoding error occurs
   */
  int decodeIntBinary(final ReadableByteBuf buf, final int length) throws SQLDataException;

  /**
   * Parse long text encoded value
   *
   * @param buf row buffer
   * @param length data length
   * @return long value
   * @throws SQLDataException if any decoding error occurs
   */
  long decodeLongText(final ReadableByteBuf buf, final int length) throws SQLDataException;
  /**
   * Parse long binary encoded value
   *
   * @param buf row buffer
   * @param length data length
   * @return long value
   * @throws SQLDataException if any decoding error occurs
   */
  long decodeLongBinary(final ReadableByteBuf buf, final int length) throws SQLDataException;

  /**
   * Parse float text encoded value
   *
   * @param buf row buffer
   * @param length data length
   * @return float value
   * @throws SQLDataException if any decoding error occurs
   */
  float decodeFloatText(final ReadableByteBuf buf, final int length) throws SQLDataException;

  /**
   * Parse float binary encoded value
   *
   * @param buf row buffer
   * @param length data length
   * @return float value
   * @throws SQLDataException if any decoding error occurs
   */
  float decodeFloatBinary(final ReadableByteBuf buf, final int length) throws SQLDataException;

  /**
   * Parse double text encoded value
   *
   * @param buf row buffer
   * @param length data length
   * @return double value
   * @throws SQLDataException if any decoding error occurs
   */
  double decodeDoubleText(final ReadableByteBuf buf, final int length) throws SQLDataException;

  /**
   * Parse double binary encoded value
   *
   * @param buf row buffer
   * @param length data length
   * @return double value
   * @throws SQLDataException if any decoding error occurs
   */
  double decodeDoubleBinary(final ReadableByteBuf buf, final int length) throws SQLDataException;

  /**
   * Decode Column from mysql packet
   *
   * @param buf packet
   * @param extendedInfo is extended datatype information capability enable
   * @return column
   */
  static ColumnDecoder decode(ReadableByteBuf buf, boolean extendedInfo) {
    // skip first strings
    int[] stringPos = new int[5];
    stringPos[0] = buf.skipIdentifier(); // schema pos
    stringPos[1] = buf.skipIdentifier(); // table alias pos
    stringPos[2] = buf.skipIdentifier(); // table pos
    stringPos[3] = buf.skipIdentifier(); // column alias pos
    stringPos[4] = buf.skipIdentifier(); // column pos
    buf.skipIdentifier();

    String extTypeName = null;
    String extTypeFormat = null;
    if (extendedInfo) {
      // fast skipping extended info (usually not set)
      if (buf.readByte() != 0) {
        // revert position, because has extended info.
        buf.pos(buf.pos() - 1);

        ReadableByteBuf subPacket = buf.readLengthBuffer();
        while (subPacket.readableBytes() > 0) {
          switch (subPacket.readByte()) {
            case 0:
              extTypeName = subPacket.readAscii(subPacket.readLength());
              break;
            case 1:
              extTypeFormat = subPacket.readAscii(subPacket.readLength());
              break;
            default: // skip data
              subPacket.skip(subPacket.readLength());
              break;
          }
        }
      }
    }

    buf.skip(); // skip length always 0x0c
    short charset = buf.readShort();
    int length = buf.readInt();
    DataType dataType = DataType.of(buf.readUnsignedByte());
    int flags = buf.readUnsignedShort();
    byte decimals = buf.readByte();
    DataType.ColumnConstructor constructor =
        (extTypeName != null && extTypeName.equals("uuid"))
            ? UuidColumn::new
            : (flags & ColumnFlags.UNSIGNED) == 0
                ? dataType.getColumnConstructor()
                : dataType.getUnsignedColumnConstructor();
    return constructor.create(
        buf, charset, length, dataType, decimals, flags, stringPos, extTypeName, extTypeFormat);
  }

  /**
   * Create fake MySQL column definition packet with indicated datatype
   *
   * @param name column name
   * @param type data type
   * @param flags column flags
   * @return Column
   */
  static ColumnDecoder create(String name, DataType type, int flags) {
    byte[] nameBytes = name.getBytes(StandardCharsets.UTF_8);
    byte[] arr = new byte[9 + 2 * nameBytes.length];
    arr[0] = 3;
    arr[1] = 'D';
    arr[2] = 'E';
    arr[3] = 'F';

    int[] stringPos = new int[5];
    stringPos[0] = 4; // schema pos
    stringPos[1] = 5; // table alias pos
    stringPos[2] = 6; // table pos

    // lenenc_str     name
    // lenenc_str     org_name
    int pos = 7;
    for (int i = 0; i < 2; i++) {
      stringPos[i + 3] = pos;
      arr[pos++] = (byte) nameBytes.length;
      System.arraycopy(nameBytes, 0, arr, pos, nameBytes.length);
      pos += nameBytes.length;
    }
    int len;

    /* Sensible predefined length - since we're dealing with I_S here, most char fields are 64 char long */
    switch (type) {
      case VARCHAR:
      case VARSTRING:
        len = 64 * 3; /* 3 bytes per UTF8 char */
        break;
      case SMALLINT:
        len = 5;
        break;
      case NULL:
        len = 0;
        break;
      default:
        len = 1;
        break;
    }
    DataType.ColumnConstructor constructor =
        (flags & ColumnFlags.UNSIGNED) == 0
            ? type.getColumnConstructor()
            : type.getUnsignedColumnConstructor();
    return constructor.create(
        new StandardReadableByteBuf(arr, arr.length),
        33,
        len,
        type,
        (byte) 0,
        flags,
        stringPos,
        null,
        null);
  }
}
