// 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.*;
import java.sql.*;
import java.util.Locale;
import org.junit.jupiter.api.*;

public class LocalInfileTest extends Common {
  @BeforeAll
  public static void beforeAll2() throws SQLException {
    drop();
    Statement stmt = sharedConn.createStatement();
    stmt.execute("CREATE TABLE LocalInfileInputStreamTest(id int, test varchar(100))");
    stmt.execute("CREATE TABLE LocalInfileInputStreamTest2(id int, test varchar(100))");
    stmt.execute("CREATE TABLE ttlocal(id int, test varchar(100))");
    stmt.execute("CREATE TABLE ldinfile(a varchar(10))");
    stmt.execute(
        "CREATE TABLE `infile`(`a` varchar(50) DEFAULT NULL, `b` varchar(50) DEFAULT NULL)"
            + " ENGINE=InnoDB DEFAULT CHARSET=latin1");
    stmt.execute(
        "CREATE TABLE big_load_data_infile(id int not null primary key auto_increment, name"
            + " char(20)) ENGINE=myisam");
    stmt.execute("FLUSH TABLES");
  }

  @AfterAll
  public static void drop() throws SQLException {
    Statement stmt = sharedConn.createStatement();
    stmt.execute("DROP TABLE IF EXISTS AllowMultiQueriesTest");
    stmt.execute("DROP TABLE IF EXISTS LocalInfileInputStreamTest");
    stmt.execute("DROP TABLE IF EXISTS LocalInfileInputStreamTest2");
    stmt.execute("DROP TABLE IF EXISTS ttlocal");
    stmt.execute("DROP TABLE IF EXISTS ldinfile");
    stmt.execute("DROP TABLE IF EXISTS `infile`");
    stmt.execute("DROP TABLE IF EXISTS big_load_data_infile");
  }

  private static boolean checkLocal() throws SQLException {
    Statement stmt = sharedConn.createStatement();
    ResultSet rs = stmt.executeQuery("SELECT @@local_infile");
    if (rs.next()) {
      return rs.getInt(1) == 1;
    }
    return false;
  }

  @Test
  public void bigLoadDataInfileTest() throws SQLException, IOException {
    Assumptions.assumeTrue(runLongTest());
    try (VeryLongAutoGeneratedInputStream in = new VeryLongAutoGeneratedInputStream(5000000)) {
      try (Connection connection = createCon("&allowLocalInfile=true")) {
        Statement statement = connection.createStatement();
        org.mariadb.jdbc.Statement mariaDbStatement =
            statement.unwrap(org.mariadb.jdbc.Statement.class);
        mariaDbStatement.setLocalInfileInputStream(in);

        String sql =
            "LOAD DATA LOCAL INFILE 'dummyFileName'"
                + " INTO TABLE big_load_data_infile "
                + " FIELDS TERMINATED BY '\\t' ENCLOSED BY ''"
                + " ESCAPED BY '\\\\' LINES TERMINATED BY '\\n'";

        assertFalse(statement.execute(sql));
        ResultSet rs = statement.executeQuery("select count(*) from big_load_data_infile");
        assertTrue(rs.next());
        assertEquals(in.numberOfRows, rs.getInt(1));
      }
    }
  }

  /** Custom memory conserving generator of a LOAD DATA INFILE that generates a stream. */
  private static class VeryLongAutoGeneratedInputStream extends InputStream {

    private final int numberOfRows;
    private int currentPosInBuffer;
    private byte[] buffer;
    private int currentRow;

    private VeryLongAutoGeneratedInputStream(int numberOfRows) {
      this.numberOfRows = numberOfRows;
      currentRow = 0;
    }

    @Override
    public int read() {
      if (currentRow > numberOfRows) {
        return -1;
      }
      if (buffer != null && currentPosInBuffer >= buffer.length) {
        buffer = null;
      }
      if (buffer == null) {
        currentRow++;
        currentPosInBuffer = 0;
        buffer = (currentRow + "\tname" + currentRow + "\n").getBytes();
      }
      return buffer[currentPosInBuffer++];
    }
  }

  @Test
  public void streamInBatch() throws SQLException, IOException {
    Assumptions.assumeFalse((!isMariaDBServer() && minVersion(8, 0, 3)));
    Assumptions.assumeTrue(
        !"skysql".equals(System.getenv("srv")) && !"skysql-ha".equals(System.getenv("srv")));
    String batch_update =
        "LOAD DATA LOCAL INFILE 'dummy.tsv' INTO TABLE LocalInfileInputStreamTest2 (id, test)";
    String builder = "1\thello\n2\tworld\n";

    Statement stmt = sharedConn.createStatement();
    stmt.execute("TRUNCATE LocalInfileInputStreamTest2");
    InputStream inputStream = new ByteArrayInputStream(builder.getBytes());
    ((org.mariadb.jdbc.Statement) stmt).setLocalInfileInputStream(inputStream);
    stmt.addBatch(batch_update);
    stmt.addBatch("SET UNIQUE_CHECKS=1");
    stmt.executeBatch();
    stmt.addBatch(batch_update);
    try {
      stmt.executeBatch();
    } catch (SQLException e) {
      assertTrue(e.getCause().getCause() instanceof FileNotFoundException);
    }

    try (PreparedStatement prep =
        sharedConn.prepareStatement(
            "LOAD DATA LOCAL INFILE 'dummy.tsv' INTO TABLE LocalInfileInputStreamTest2 (id,"
                + " test)")) {
      inputStream = new ByteArrayInputStream(builder.getBytes());
      ((org.mariadb.jdbc.Statement) prep).setLocalInfileInputStream(inputStream);
      prep.addBatch();
      prep.executeBatch();
      try {
        prep.addBatch();
        prep.executeBatch();
      } catch (SQLException e) {
        assertTrue(e.getCause().getCause() instanceof FileNotFoundException);
      }
    }
    try (PreparedStatement prep =
        sharedConnBinary.prepareStatement(
            "LOAD DATA LOCAL INFILE 'dummy.tsv' INTO TABLE LocalInfileInputStreamTest2 (id,"
                + " test)")) {
      inputStream = new ByteArrayInputStream(builder.getBytes());
      ((org.mariadb.jdbc.Statement) prep).setLocalInfileInputStream(inputStream);
      prep.addBatch();
      prep.executeBatch();
      try {
        prep.addBatch();
        prep.executeBatch();
      } catch (SQLException e) {
        assertTrue(e.getCause().getCause() instanceof FileNotFoundException);
      }
    }
  }

  @Test
  public void throwExceptions() throws Exception {
    Assumptions.assumeTrue(
        (isMariaDBServer() || !minVersion(8, 0, 3))
            && !"skysql".equals(System.getenv("srv"))
            && !"skysql-ha".equals(System.getenv("srv")));

    // https://jira.mariadb.org/browse/XPT-270
    Assumptions.assumeFalse(isXpand());

    try (Connection con = createCon("&allowLocalInfile=false")) {
      Statement stmt = con.createStatement();
      stmt.execute("TRUNCATE LocalInfileInputStreamTest2");
      Common.assertThrowsContains(
          SQLException.class,
          () ->
              stmt.execute(
                  "LOAD DATA LOCAL INFILE 'someFile' INTO TABLE LocalInfileInputStreamTest2 (id,"
                      + " test)"),
          "Local infile is disabled by connector. Enable `allowLocalInfile` to allow local infile"
              + " commands");
      stmt.addBatch(
          "LOAD DATA LOCAL INFILE 'someFile' INTO TABLE LocalInfileInputStreamTest2 (id, test)");
      stmt.addBatch("SET UNIQUE_CHECKS=1");

      try {
        stmt.executeBatch();
        fail();
      } catch (SQLException e) {
        assertEquals(e.getClass(), BatchUpdateException.class);
        assertTrue(
            e.getMessage()
                .contains(
                    "Local infile is disabled by connector. Enable `allowLocalInfile` to allow"
                        + " local infile commands"));
        assertNotNull(e.getCause());
        assertEquals(e.getCause().getMessage(), e.getMessage());
        assertEquals(((SQLException) e.getCause()).getSQLState(), e.getSQLState());
        assertEquals(((SQLException) e.getCause()).getErrorCode(), e.getErrorCode());
      }

      try (PreparedStatement prep =
          con.prepareStatement(
              "LOAD DATA LOCAL INFILE ? INTO TABLE LocalInfileInputStreamTest2 (id, test)")) {
        prep.setString(1, "someFile");
        Common.assertThrowsContains(
            SQLException.class,
            prep::execute,
            "Local infile is disabled by connector. Enable `allowLocalInfile` to allow local infile"
                + " commands");
      }
    }
  }

  @Test
  public void wrongFile() throws Exception {
    Assumptions.assumeTrue(checkLocal());
    Assumptions.assumeTrue(
        !"skysql".equals(System.getenv("srv")) && !"skysql-ha".equals(System.getenv("srv")));

    try (Connection con = createCon("allowLocalInfile")) {
      Statement stmt = con.createStatement();
      Common.assertThrowsContains(
          SQLException.class,
          () ->
              stmt.execute(
                  "LOAD DATA LOCAL INFILE 'someFile' INTO TABLE LocalInfileInputStreamTest2 (id,"
                      + " test)"),
          "Could not send file : someFile");
      assertTrue(con.isValid(1));
    }
  }

  @Test
  public void unReadableFile() throws Exception {
    Assumptions.assumeTrue(checkLocal());
    Assumptions.assumeTrue(
        !"skysql".equals(System.getenv("srv"))
            && !"skysql-ha".equals(System.getenv("srv"))
            && !System.getProperty("os.name").toLowerCase(Locale.ROOT).contains("win"));

    try (Connection con = createCon("allowLocalInfile")) {
      File tempFile = File.createTempFile("hello", ".tmp");
      tempFile.deleteOnExit();
      tempFile.setReadable(false);
      Statement stmt = con.createStatement();
      Common.assertThrowsContains(
          SQLException.class,
          () ->
              stmt.execute(
                  "LOAD DATA LOCAL INFILE '"
                      + tempFile.getCanonicalPath().replace("\\", "/")
                      + "' INTO TABLE LocalInfileInputStreamTest2 (id, test)"),
          "Could not send file");
      assertTrue(con.isValid(1));
    }
  }

  @Test
  public void loadDataBasic() throws Exception {
    Assumptions.assumeTrue(checkLocal());
    Assumptions.assumeTrue(
        !"skysql".equals(System.getenv("srv")) && !"skysql-ha".equals(System.getenv("srv")));
    File temp = File.createTempFile("dummyloadDataBasic", ".txt");
    try (BufferedWriter bw = new BufferedWriter(new FileWriter(temp))) {
      bw.write("1\thello2\n2\tworld\n");
    }

    try (Connection con = createCon("allowLocalInfile")) {
      Statement stmt = con.createStatement();
      stmt.execute("TRUNCATE LocalInfileInputStreamTest2");
      stmt.execute(
          "LOAD DATA LOCAL INFILE '"
              + temp.getCanonicalPath().replace("\\", "/")
              + "' INTO TABLE LocalInfileInputStreamTest2 (id, test)");
      ResultSet rs = stmt.executeQuery("SELECT * FROM LocalInfileInputStreamTest2");
      assertTrue(rs.next());
      assertEquals(1, rs.getInt(1));
      assertEquals("hello2", rs.getString(2));
      assertTrue(rs.next());
      assertEquals(2, rs.getInt(1));
      assertEquals("world", rs.getString(2));
      while (rs.next()) {
        System.out.println(rs.getString(2));
      }
      assertFalse(rs.next());

      stmt.execute("TRUNCATE LocalInfileInputStreamTest2");
      stmt.addBatch(
          "LOAD DATA LOCAL INFILE '"
              + temp.getCanonicalPath().replace("\\", "/")
              + "' INTO TABLE LocalInfileInputStreamTest2 (id, test)");
      stmt.addBatch("SET UNIQUE_CHECKS=1");
      stmt.executeBatch();

      rs = stmt.executeQuery("SELECT * FROM LocalInfileInputStreamTest2");
      assertTrue(rs.next());
      assertEquals(1, rs.getInt(1));
      assertEquals("hello2", rs.getString(2));
      assertTrue(rs.next());
      assertEquals(2, rs.getInt(1));
      assertEquals("world", rs.getString(2));
      assertFalse(rs.next());
    } finally {
      temp.delete();
    }
  }

  @Test
  public void loadDataValidationFails() throws Exception {
    Assumptions.assumeTrue(checkLocal());
    loadDataValidationFails(false);
    loadDataValidationFails(true);
  }

  public void loadDataValidationFails(boolean prepStmt) throws Exception {
    File temp = File.createTempFile("dummy", ".txt");
    File tempXml = File.createTempFile("xmldummy", ".txt");

    try (Connection con = createCon("&allowLocalInfile&useServerPrepStmts=" + prepStmt)) {
      try (BufferedWriter bw = new BufferedWriter(new FileWriter(temp))) {
        bw.write("1\thello\n2\tworld\n");
      }
      try (BufferedWriter bw = new BufferedWriter(new FileWriter(tempXml))) {
        bw.write("<row id=\"1\" test=\"hello\" />\n<row id=\"2\" test=\"world\" />\n");
      }
      try (PreparedStatement prep =
          con.prepareStatement(
              "LOAD DATA LOCAL INFILE ? INTO TABLE LocalInfileInputStreamTest2 (id, test)")) {
        prep.setString(1, temp.getCanonicalPath().replace("\\", "/"));
        prep.execute();
      }
      try (PreparedStatement prep =
          con.prepareStatement(
              "LOAD XML LOCAL INFILE ? INTO TABLE LocalInfileInputStreamTest2 (id, test)")) {
        prep.setString(1, tempXml.getCanonicalPath().replace("\\", "/"));
        prep.execute();
      }
      try (PreparedStatement prep =
          con.prepareStatement(
              "/* test */ LOAD  DATA LOCAL INFILE 'j' INTO TABLE LocalInfileInputStreamTest2 (id,"
                  + " test)")) {
        assertThrowsContains(SQLException.class, () -> prep.execute(), "Could not send file : j");
      }
      // special test comment inside LOAD DATA LOCAL are not checked, resulting in error
      try (PreparedStatement prep =
          con.prepareStatement(
              "LOAD /**g*/ DATA LOCAL INFILE 'h' INTO TABLE LocalInfileInputStreamTest2 (id,"
                  + " test)")) {
        assertThrowsContains(
            SQLException.class,
            () -> prep.execute(),
            "LOAD DATA LOCAL INFILE asked for file 'h' that doesn't correspond to initial query ");
      }
      // ensure connection state after errors
      ResultSet rs = con.createStatement().executeQuery("SELECT 1");
      rs.next();
      assertEquals(1, rs.getInt(1));
    } finally {
      temp.delete();
      tempXml.delete();
    }
  }

  @Test
  public void loadDataInfileEmpty() throws SQLException, IOException {
    Assumptions.assumeTrue(
        (isMariaDBServer() || !minVersion(8, 0, 3))
            && !"skysql".equals(System.getenv("srv"))
            && !"skysql-ha".equals(System.getenv("srv")));
    // Create temp file.
    File temp = File.createTempFile("validateInfile", ".tmp");
    try (Connection connection = createCon("&allowLocalInfile=true")) {
      Statement st = connection.createStatement();
      st.execute(
          "LOAD DATA LOCAL INFILE '"
              + temp.getAbsolutePath().replace('\\', '/')
              + "' INTO TABLE ldinfile");
      try (ResultSet rs = st.executeQuery("SELECT * FROM ldinfile")) {
        assertFalse(rs.next());
      }
    } finally {
      temp.delete();
    }
  }

  private File createTmpData(long recordNumber) throws Exception {
    File file = File.createTempFile("infile" + recordNumber, ".tmp");

    // write it
    try (BufferedWriter writer = new BufferedWriter(new FileWriter(file))) {
      // Every row is 8 bytes to make counting easier
      for (long i = 0; i < recordNumber; i++) {
        writer.write("\"a\",\"b\"");
        writer.write("\n");
      }
    }

    return file;
  }

  private void checkBigLocalInfile(long fileSize) throws Exception {
    long recordNumber = fileSize / 8;
    try (Connection connection = createCon("allowLocalInfile")) {
      Statement stmt = connection.createStatement();
      stmt.execute("truncate `infile`");
      File file = createTmpData(recordNumber);
      int insertNumber =
          stmt.executeUpdate(
              "LOAD DATA LOCAL INFILE '"
                  + file.getCanonicalPath().replace("\\", "/")
                  + "' "
                  + "INTO TABLE `infile` "
                  + "COLUMNS TERMINATED BY ',' ENCLOSED BY '\\\"' ESCAPED BY '\\\\' "
                  + "LINES TERMINATED BY '\\n' (`a`, `b`)");
      assertEquals(insertNumber, recordNumber);
      file.delete();
      stmt.setFetchSize(1000); // to avoid using too much memory for tests
      try (ResultSet rs = stmt.executeQuery("SELECT * FROM `infile`")) {
        for (int i = 0; i < recordNumber; i++) {
          assertTrue(rs.next());
          assertEquals("a", rs.getString(1));
          assertEquals("b", rs.getString(2));
        }
        assertFalse(rs.next());
      }
    }
  }

  @Test
  public void testSmallBigLocalInfileInputStream() throws Exception {
    Assumptions.assumeTrue(
        (isMariaDBServer() || !minVersion(8, 0, 3))
            && !"skysql".equals(System.getenv("srv"))
            && !"skysql-ha".equals(System.getenv("srv")));
    checkBigLocalInfile(256);
  }

  @Test
  public void test2xBigLocalInfileInputStream() throws Exception {
    Assumptions.assumeTrue(
        ((isMariaDBServer() || !minVersion(8, 0, 3)) && runLongTest())
            && !"skysql".equals(System.getenv("srv"))
            && !"skysql-ha".equals(System.getenv("srv")));
    checkBigLocalInfile(16777216 * 2);
  }

  @Test
  public void testMoreThanMaxAllowedPacketLocalInfileInputStream() throws Exception {
    Assumptions.assumeTrue(
        (isMariaDBServer() || !minVersion(8, 0, 3))
            && !"skysql".equals(System.getenv("srv"))
            && !"skysql-ha".equals(System.getenv("srv")));
    Assumptions.assumeTrue(runLongTest());
    Statement stmt = sharedConn.createStatement();
    ResultSet rs = stmt.executeQuery("select @@max_allowed_packet");
    assertTrue(rs.next());
    long maxAllowedPacket = rs.getLong(1);
    Assumptions.assumeTrue(maxAllowedPacket < 100_000_000);
    checkBigLocalInfile(maxAllowedPacket + 1024);
  }
}
