// SPDX-License-Identifier: LGPL-2.1-or-later
// Copyright (c) 2012-2014 Monty Program Ab
// Copyright (c) 2015-2021 MariaDB Corporation Ab

package org.mariadb.jdbc.integration;

import static org.junit.jupiter.api.Assertions.*;

import java.io.ByteArrayInputStream;
import java.io.StringReader;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.net.URL;
import java.nio.charset.StandardCharsets;
import java.sql.*;
import java.util.Calendar;
import java.util.TimeZone;
import org.junit.jupiter.api.AfterAll;
import org.junit.jupiter.api.Assumptions;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Test;
import org.mariadb.jdbc.Connection;
import org.mariadb.jdbc.MariaDbBlob;
import org.mariadb.jdbc.MariaDbClob;
import org.mariadb.jdbc.Statement;

public class PreparedStatementParametersTest extends Common {

  @BeforeAll
  public static void beforeAll2() throws SQLException {
    drop();
    Statement stmt = sharedConn.createStatement();
    stmt.execute("CREATE TABLE bigTest (t1 int not null primary key auto_increment, t2 LONGTEXT)");
    stmt.execute("CREATE TABLE prepareParam (t1 BLOB(20))");
    stmt.execute("CREATE TABLE prepareParam2 (t1 BIGINT)");
    stmt.execute("CREATE TABLE prepareParam3 (t1 DOUBLE)");
    stmt.execute(
        "CREATE TABLE prepareParam4 (t1 VARCHAR(30)) "
            + "CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci");
    stmt.execute("CREATE TABLE prepareParam5 (t1 TIMESTAMP(6))");
    stmt.execute("CREATE TABLE prepareParam6 (t1 BIGINT)");
    stmt.execute("CREATE TABLE prepareParam7 (t1 TIME(6))");
    stmt.execute("FLUSH TABLES");
  }

  @AfterAll
  public static void drop() throws SQLException {
    Statement stmt = sharedConn.createStatement();
    stmt.execute("DROP TABLE IF EXISTS bigTest");
    stmt.execute("DROP TABLE IF EXISTS prepareParam");
    stmt.execute("DROP TABLE IF EXISTS prepareParam2");
    stmt.execute("DROP TABLE IF EXISTS prepareParam3");
    stmt.execute("DROP TABLE IF EXISTS prepareParam4");
    stmt.execute("DROP TABLE IF EXISTS prepareParam5");
    stmt.execute("DROP TABLE IF EXISTS prepareParam6");
    stmt.execute("DROP TABLE IF EXISTS prepareParam7");
  }

  @Test
  public void validateParameters() throws Exception {
    // error crashing maxscale 6.1.x
    Assumptions.assumeTrue(
        !sharedConn.getMetaData().getDatabaseProductVersion().contains("maxScale-6.1.")
            && !"skysql-ha".equals(System.getenv("srv")));
    validateParameters(sharedConn);
    validateParameters(sharedConnBinary);
  }

  public void validateParameters(Connection con) throws Exception {
    try (PreparedStatement prep = con.prepareStatement("INSERT INTO prepareParam6 VALUES (?)")) {
      try {
        prep.execute();
        fail();
      } catch (SQLException sqle) {
        // eat
      }
    }
    try (PreparedStatement prep = con.prepareStatement("INSERT INTO prepareParam6 VALUES (?)")) {
      prep.setInt(1, 1);
      prep.execute();
      prep.clearParameters();
      Common.assertThrowsContains(
          SQLTransientConnectionException.class,
          prep::execute,
          "Parameter at position 1 is not set");
    }
  }

  @Test
  public void checkParameters() throws Exception {
    checkParameters(sharedConn, true);
    checkParameters(sharedConnBinary, false);
  }

  @SuppressWarnings("deprecation")
  public void checkParameters(org.mariadb.jdbc.Connection con, boolean text) throws Exception {
    Calendar utcCal = Calendar.getInstance(TimeZone.getTimeZone("UTC"));
    checkSendBlob(
        ps -> ps.setBlob(1, new MariaDbBlob("0123".getBytes(), 1, 2)),
        rs -> assertArrayEquals("12".getBytes(), rs.getBytes(1)),
        con);
    checkSendBlob(
        ps -> ps.setBlob(1, new MariaDbBlob("0123".getBytes(), 1, 2).getBinaryStream()),
        rs -> assertArrayEquals("12".getBytes(), rs.getBytes(1)),
        con);
    checkSendBlob(
        ps -> ps.setBlob(1, new MariaDbBlob("01234".getBytes(), 1, 3).getBinaryStream(), 2),
        rs -> assertArrayEquals("12".getBytes(), rs.getBytes(1)),
        con);
    checkSendBlob(
        ps -> ps.setBlob(1, new MariaDbBlob("01234".getBytes(), 1, 3).getBinaryStream(), 2L),
        rs -> assertArrayEquals("12".getBytes(), rs.getBytes(1)),
        con);
    checkSendBlob(ps -> ps.setNull(1, Types.VARBINARY), rs -> assertNull(rs.getObject(1)), con);
    checkSendBlob(
        ps -> ps.setNull(1, Types.VARBINARY, String.class.getName()),
        rs -> assertNull(rs.getObject(1)),
        con);
    checkSendLong(ps -> ps.setBoolean(1, true), rs -> assertTrue(rs.getBoolean(1)), con);
    checkSendLong(ps -> ps.setBoolean(1, false), rs -> assertFalse(rs.getBoolean(1)), con);
    checkSendLong(
        ps -> ps.setByte(1, (byte) 0x58), rs -> assertEquals((byte) 0x58, rs.getByte(1)), con);
    checkSendLong(
        ps -> ps.setShort(1, (short) 127), rs -> assertEquals((short) 127, rs.getShort(1)), con);
    checkSendLong(ps -> ps.setInt(1, -555), rs -> assertEquals(-555, rs.getInt(1)), con);
    checkSendLong(ps -> ps.setLong(1, -999L), rs -> assertEquals(-999L, rs.getLong(1)), con);
    checkSendDouble(
        ps -> ps.setFloat(1, -56.59F), rs -> assertEquals(-56.59F, rs.getFloat(1), 0.01F), con);
    checkSendDouble(
        ps -> ps.setDouble(1, -56.59D), rs -> assertEquals(-56.59D, rs.getDouble(1), 0.01D), con);
    checkSendDouble(
        ps -> ps.setBigDecimal(1, new BigDecimal("-156.59")),
        rs ->
            assertEquals(
                new BigDecimal("-156.59"), rs.getBigDecimal(1).setScale(2, RoundingMode.HALF_DOWN)),
        con);
    checkSendString(
        ps -> ps.setString(1, "你好(hello in Chinese)"),
        rs -> assertEquals("你好(hello in Chinese)", rs.getString(1)),
        con);
    checkSendString(
        ps -> ps.setNString(1, "你好(hello in Chinese)"),
        rs -> assertEquals("你好(hello in Chinese)", rs.getNString(1)),
        con);
    checkSendBlob(
        ps -> ps.setBytes(1, "01234".getBytes()),
        rs -> assertArrayEquals("01234".getBytes(), rs.getBytes(1)),
        con);
    checkSendTimestamp(
        ps -> ps.setDate(1, Date.valueOf("2010-05-25")),
        rs -> assertEquals(Date.valueOf("2010-05-25"), rs.getDate(1)),
        con);
    boolean minus = TimeZone.getDefault().getOffset(System.currentTimeMillis()) > 0;
    checkSendTimestamp(
        ps -> ps.setDate(1, Date.valueOf("2010-01-12"), utcCal),
        rs ->
            assertEquals(minus ? 1263164400000L : 1263254400000L, rs.getDate(1, utcCal).getTime()),
        con);
    checkSendTimestamp(
        ps -> ps.setDate(1, Date.valueOf("2010-01-12"), utcCal),
        rs -> assertEquals(minus ? "2010-01-11" : "2010-01-12", rs.getDate(1, utcCal).toString()),
        con);
    checkSendTimestamp(
        ps -> ps.setDate(1, Date.valueOf("2010-05-25")),
        rs -> assertEquals(Date.valueOf("2010-05-25").getTime(), rs.getDate(1).getTime()),
        con);
    if (isXpand()) {
      // skip due to error https://jira.mariadb.org/browse/XPT-265
    } else {
      if (text) {
        Common.assertThrowsContains(
            SQLException.class,
            () ->
                checkSendTimestamp(
                    ps -> ps.setTime(1, new Time(Time.valueOf("18:16:01").getTime() + 123)),
                    rs ->
                        assertEquals(
                            Time.valueOf("18:16:01").getTime() + 123, rs.getTime(1).getTime()),
                    con),
            "Incorrect datetime value: '18:16:01.123'");
      } else {
        checkSendTimestamp(
            ps -> ps.setTime(1, new Time(Time.valueOf("18:16:01").getTime() + 123)),
            rs -> assertEquals(Time.valueOf("18:16:01").getTime() + 123, rs.getTime(1).getTime()),
            con);
      }
    }

    checkSendTimestamp(
        ps -> ps.setTimestamp(1, Timestamp.valueOf("2010-05-25 18:16:01.987")),
        rs ->
            assertEquals(
                Timestamp.valueOf("2010-05-25 18:16:01.987").getTime(),
                rs.getTimestamp(1).getTime()),
        con);
    checkSendTimestamp(
        ps -> ps.setTimestamp(1, Timestamp.valueOf("2010-05-25 18:16:01.987")),
        rs -> assertEquals("2010-05-25 18:16:01.987", rs.getTimestamp(1).toString()),
        con);
    checkSendTimestamp(
        ps -> ps.setTimestamp(1, Timestamp.valueOf("2010-05-25 18:16:01.987"), utcCal),
        rs ->
            assertEquals(
                Timestamp.valueOf("2010-05-25 18:16:01.987").getTime(),
                rs.getTimestamp(1, utcCal).getTime()),
        con);

    checkSendTimestamp(
        ps -> ps.setTimestamp(1, Timestamp.valueOf("2010-05-25 18:16:01.987"), utcCal),
        rs ->
            assertEquals(
                Timestamp.valueOf("2010-05-25 18:16:01.987").getTime()
                    - TimeZone.getDefault().getOffset(1, 2010, 5, 25, 1, 987),
                rs.getTimestamp(1).getTime()),
        con);
    checkSendString(
        ps -> ps.setAsciiStream(1, new ByteArrayInputStream("abcdef".getBytes())),
        rs -> assertEquals("abcdef", rs.getString(1)),
        con);
    checkSendString(
        ps -> ps.setAsciiStream(1, new ByteArrayInputStream("abcdef".getBytes()), 5),
        rs -> assertEquals("abcde", rs.getString(1)),
        con);
    checkSendString(
        ps -> ps.setAsciiStream(1, new ByteArrayInputStream("abcdef".getBytes()), 5L),
        rs -> assertEquals("abcde", rs.getString(1)),
        con);
    final String unicodeString =
        ""
            + "\uD83D\uDE0E" // 😎 unicode 6 smiling face with sunglasses
            + "\uD83C\uDF36" // 🌶 unicode 7 hot pepper
            + "\uD83C\uDFA4" // 🎤 unicode 8 no microphones
            + "\uD83E\uDD42 "; // 🥂 unicode 9 clinking glasses
    final byte[] unicodeBytes = unicodeString.getBytes(StandardCharsets.UTF_8);
    checkSendString(
        ps -> ps.setUnicodeStream(1, new ByteArrayInputStream(unicodeBytes), 16),
        rs ->
            assertEquals(
                unicodeString.substring(0, 8),
                rs.getString(1),
                "expected " + unicodeString.substring(0, 8) + " but is " + rs.getString(1)),
        con);
    checkSendString(
        ps -> ps.setBinaryStream(1, new ByteArrayInputStream(unicodeBytes)),
        rs -> assertEquals(unicodeString, rs.getString(1)),
        con);
    checkSendString(
        ps -> ps.setBinaryStream(1, new ByteArrayInputStream(unicodeBytes), 16),
        rs -> assertEquals(unicodeString.substring(0, 8), rs.getString(1)),
        con);
    checkSendString(
        ps -> ps.setBinaryStream(1, new ByteArrayInputStream(unicodeBytes), 16L),
        rs -> assertEquals(unicodeString.substring(0, 8), rs.getString(1)),
        con);
    checkSendString(
        ps -> ps.setCharacterStream(1, new StringReader(unicodeString)),
        rs -> assertEquals(unicodeString, rs.getString(1)),
        con);
    checkSendString(
        ps -> ps.setCharacterStream(1, new StringReader(unicodeString), 8),
        rs -> assertEquals(unicodeString.substring(0, 8), rs.getString(1)),
        con);
    checkSendString(
        ps -> ps.setCharacterStream(1, new StringReader(unicodeString), 8L),
        rs -> assertEquals(unicodeString.substring(0, 8), rs.getString(1)),
        con);
    checkSendString(
        ps -> ps.setNCharacterStream(1, new StringReader(unicodeString)),
        rs -> assertEquals(unicodeString, rs.getString(1)),
        con);
    checkSendString(
        ps -> ps.setNCharacterStream(1, new StringReader(unicodeString), 8),
        rs -> assertEquals(unicodeString.substring(0, 8), rs.getString(1)),
        con);
    checkSendString(
        ps -> ps.setNCharacterStream(1, new StringReader(unicodeString), 8L),
        rs -> assertEquals(unicodeString.substring(0, 8), rs.getString(1)),
        con);
    checkSendString(
        ps -> ps.setClob(1, new MariaDbClob(unicodeBytes, 0, 16)),
        rs -> assertEquals(unicodeString.substring(0, 8), rs.getString(1)),
        con);
    checkSendString(
        ps -> ps.setClob(1, new StringReader(unicodeString)),
        rs -> assertEquals(unicodeString, rs.getString(1)),
        con);
    checkSendString(
        ps -> ps.setClob(1, new StringReader(unicodeString), 8),
        rs -> assertEquals(unicodeString.substring(0, 8), rs.getString(1)),
        con);
    checkSendString(
        ps -> ps.setClob(1, new StringReader(unicodeString), 8L),
        rs -> assertEquals(unicodeString.substring(0, 8), rs.getString(1)),
        con);
    checkSendString(
        ps -> ps.setNClob(1, new MariaDbClob(unicodeBytes, 0, 16)),
        rs -> assertEquals(unicodeString.substring(0, 8), rs.getString(1)),
        con);
    checkSendString(
        ps -> ps.setNClob(1, new StringReader(unicodeString)),
        rs -> assertEquals(unicodeString, rs.getString(1)),
        con);
    checkSendString(
        ps -> ps.setNClob(1, new StringReader(unicodeString), 8),
        rs -> assertEquals(unicodeString.substring(0, 8), rs.getString(1)),
        con);
    checkSendString(
        ps -> ps.setNClob(1, new StringReader(unicodeString), 8L),
        rs -> assertEquals(unicodeString.substring(0, 8), rs.getString(1)),
        con);
    checkSendString(
        ps -> ps.setURL(1, new URL("https://www.someUrl.com")),
        rs -> assertEquals("https://www.someUrl.com", rs.getString(1)),
        con);
    // TODO SET OBJECT
  }

  @Test
  public void checkTimeParameters() throws Exception {
    checkTimeParameters(sharedConn);
    checkTimeParameters(sharedConnBinary);
  }

  @SuppressWarnings("deprecation")
  public void checkTimeParameters(Connection con) throws Exception {
    Calendar utcCal = Calendar.getInstance(TimeZone.getTimeZone("UTC"));
    checkSendTime(
        ps -> ps.setTime(1, new Time(Time.valueOf("18:16:01").getTime())),
        rs -> assertEquals("18:16:01", rs.getTime(1).toString()),
        con);
    checkSendTime(
        ps -> ps.setTime(1, new Time(Time.valueOf("18:16:01").getTime()), utcCal),
        rs -> assertEquals("18:16:01", rs.getTime(1, utcCal).toString()),
        con);
    checkSendTime(
        ps -> ps.setTime(1, new Time(Time.valueOf("18:16:01").getTime() + 123), utcCal),
        rs ->
            assertEquals(
                Time.valueOf("18:16:01").getTime() + 123 - TimeZone.getDefault().getOffset(0),
                rs.getTime(1).getTime()),
        con);
  }

  @Test
  public void checkNotSupported() throws Exception {
    checkNotSupported(sharedConn);
    checkNotSupported(sharedConnBinary);
  }

  private void checkNotSupported(Connection con) throws SQLException {
    try (PreparedStatement preparedStatement = con.prepareStatement("SELECT * FROM prepareParam")) {
      Common.assertThrowsContains(
          SQLException.class,
          () -> preparedStatement.setRef(1, null),
          "REF parameter are not supported");
      Common.assertThrowsContains(
          SQLException.class,
          () -> preparedStatement.setArray(1, null),
          "Array parameter are not supported");
      Common.assertThrowsContains(
          SQLException.class,
          () -> preparedStatement.setRowId(1, null),
          "RowId parameter are not supported");
      Common.assertThrowsContains(
          SQLException.class,
          () -> preparedStatement.setSQLXML(1, null),
          "SQLXML parameter are not supported");
    }
  }

  private void checkSendBlob(
      ThrowingConsumer<PreparedStatement, Exception> consumer,
      ThrowingConsumer<ResultSet, Exception> check,
      Connection con)
      throws Exception {
    checkSend(consumer, check, "prepareParam", con);
  }

  private void checkSendLong(
      ThrowingConsumer<PreparedStatement, Exception> consumer,
      ThrowingConsumer<ResultSet, Exception> check,
      Connection con)
      throws Exception {
    checkSend(consumer, check, "prepareParam2", con);
  }

  private void checkSendDouble(
      ThrowingConsumer<PreparedStatement, Exception> consumer,
      ThrowingConsumer<ResultSet, Exception> check,
      Connection con)
      throws Exception {
    checkSend(consumer, check, "prepareParam3", con);
  }

  private void checkSendString(
      ThrowingConsumer<PreparedStatement, Exception> consumer,
      ThrowingConsumer<ResultSet, Exception> check,
      Connection con)
      throws Exception {
    checkSend(consumer, check, "prepareParam4", con);
  }

  private void checkSendTimestamp(
      ThrowingConsumer<PreparedStatement, Exception> consumer,
      ThrowingConsumer<ResultSet, Exception> check,
      Connection con)
      throws Exception {
    checkSend(consumer, check, "prepareParam5", con);
  }

  private void checkSendTime(
      ThrowingConsumer<PreparedStatement, Exception> consumer,
      ThrowingConsumer<ResultSet, Exception> check,
      Connection con)
      throws Exception {
    checkSend(consumer, check, "prepareParam7", con);
  }

  private void checkSend(
      ThrowingConsumer<PreparedStatement, Exception> consumer,
      ThrowingConsumer<ResultSet, Exception> check,
      String table,
      Connection con)
      throws Exception {
    Statement stmt = con.createStatement();
    stmt.execute("START TRANSACTION");
    try (PreparedStatement preparedStatement =
        con.prepareStatement("INSERT INTO " + table + " VALUES (?)")) {
      consumer.accept(preparedStatement);
      preparedStatement.execute();
    }
    ResultSet rs = stmt.executeQuery("SELECT * FROM " + table);
    assertTrue(rs.next());
    con.rollback();
    check.accept(rs);
  }

  @Test
  public void bigSend() throws SQLException {
    int maxAllowedPacket = getMaxAllowedPacket();
    Assumptions.assumeTrue(maxAllowedPacket > 21 * 1024 * 1024);
    char[] arr = new char[20 * 1024 * 1024];
    for (int pos = 0; pos < arr.length; pos++) {
      arr[pos] = (char) ('A' + (pos % 60));
    }
    String st = new String(arr);
    bigSend(sharedConn, st);
    bigSend(sharedConnBinary, st);
    try (Connection con = createCon("useEof=false")) {
      bigSend(con, st);
    }
  }

  public void bigSend(Connection con, String st) throws SQLException {
    Statement stmt = con.createStatement();
    stmt.execute("TRUNCATE bigTest");
    stmt.execute("START TRANSACTION"); // if MAXSCALE ensure using WRITER
    try (PreparedStatement prep = con.prepareStatement("INSERT INTO bigTest VALUES (?, ?)")) {
      prep.setInt(1, 1);
      prep.setString(2, st);
      prep.execute();
    }

    ResultSet rs = stmt.executeQuery("SELECT t2 from bigTest WHERE t1 = 1");
    assertTrue(rs.next());
    assertEquals(st, rs.getString(1));
    con.commit();
  }

  @Test
  public void bigSendError() throws SQLException {
    int maxAllowedPacket = getMaxAllowedPacket();
    Assumptions.assumeTrue(maxAllowedPacket < 32 * 1024 * 1024);
    char[] arr = new char[maxAllowedPacket];
    for (int pos = 0; pos < arr.length; pos++) {
      arr[pos] = (char) ('A' + (pos % 60));
    }
    boolean expectClosed = maxAllowedPacket >= 16 * 1024 * 1024;
    String st = new String(arr);
    try (Connection con = createCon("maxAllowedPacket=" + maxAllowedPacket)) {
      bigSendError(con, st, expectClosed);
    }
    try (Connection con =
        createCon("useServerPrepStmts=true&maxAllowedPacket=" + maxAllowedPacket)) {
      bigSendError(con, st, expectClosed);
    }
    try (Connection con = createCon("transactionReplay&maxAllowedPacket=" + maxAllowedPacket)) {
      bigSendError(con, st, expectClosed);
    }
  }

  public void bigSendError(Connection con, String st, boolean expectClose) throws SQLException {
    Statement stmt = con.createStatement();
    stmt.execute("TRUNCATE bigTest");
    stmt.execute("START TRANSACTION"); // if MAXSCALE ensure using WRITER
    try (PreparedStatement prep = con.prepareStatement("INSERT INTO bigTest VALUES (?, ?)")) {
      prep.setInt(1, 1);
      prep.setString(2, st);
      Common.assertThrowsContains(
          SQLException.class,
          prep::execute,
          "Packet too big for current server max_allowed_packet value");
      assertEquals(expectClose, con.isClosed());
    }
    if (!con.isClosed()) con.commit();
  }

  @Test
  public void bigSendErrorMax() throws SQLException {
    Assumptions.assumeTrue(
        !"maxscale".equals(System.getenv("srv"))
            && !"skysql".equals(System.getenv("srv"))
            && !"skysql-ha".equals(System.getenv("srv")));

    int maxAllowedPacket = getMaxAllowedPacket();
    Assumptions.assumeTrue(
        maxAllowedPacket > 16 * 1024 * 1024 && maxAllowedPacket < 100 * 1024 * 1024);
    char[] arr = new char[maxAllowedPacket + 100];
    for (int pos = 0; pos < arr.length; pos++) {
      arr[pos] = (char) ('A' + (pos % 60));
    }
    String st = new String(arr);
    try (Connection con = createCon("maxAllowedPacket=" + maxAllowedPacket)) {
      bigSendErrorMax(con, st, true);
    }
    try (Connection con =
        createCon("useServerPrepStmts=true&maxAllowedPacket=" + maxAllowedPacket)) {
      bigSendErrorMax(con, st, true);
    }
    try (Connection con = createCon("transactionReplay&maxAllowedPacket=" + maxAllowedPacket)) {
      bigSendError(con, st, true);
    }
  }

  public void bigSendErrorMax(Connection con, String st, boolean expectClose) throws SQLException {
    Statement stmt = con.createStatement();
    stmt.execute("TRUNCATE bigTest");
    stmt.execute("START TRANSACTION"); // if MAXSCALE ensure using WRITER
    try (PreparedStatement prep = con.prepareStatement("INSERT INTO bigTest VALUES (?, ?)")) {
      prep.setInt(1, 1);
      prep.setString(2, st);
      Common.assertThrowsContains(
          SQLNonTransientConnectionException.class,
          prep::execute,
          "Packet too big for current server max_allowed_packet value");
      assertEquals(expectClose, con.isClosed());
    }
  }

  @FunctionalInterface
  public interface ThrowingConsumer<T, E extends Exception> {
    void accept(T t) throws E;
  }
}
