/*
 * 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.geode.internal.jta.dunit;

import static org.apache.geode.distributed.ConfigurationProperties.CACHE_XML_FILE;
import static org.apache.geode.distributed.ConfigurationProperties.MCAST_PORT;
import static org.apache.geode.test.util.ResourceUtils.createTempFileFromResource;
import static org.junit.Assert.fail;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.sql.Connection;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.Properties;

import javax.naming.Context;
import javax.naming.NamingException;
import javax.sql.DataSource;

import org.apache.logging.log4j.Logger;
import org.junit.Ignore;
import org.junit.Test;

import org.apache.geode.cache.Cache;
import org.apache.geode.cache.CacheFactory;
import org.apache.geode.distributed.internal.InternalDistributedSystem;
import org.apache.geode.internal.OSProcess;
import org.apache.geode.internal.jta.CacheUtils;
import org.apache.geode.logging.internal.log4j.api.LogService;
import org.apache.geode.test.awaitility.GeodeAwaitility;
import org.apache.geode.test.dunit.Assert;
import org.apache.geode.test.dunit.AsyncInvocation;
import org.apache.geode.test.dunit.Host;
import org.apache.geode.test.dunit.RMIException;
import org.apache.geode.test.dunit.ThreadUtils;
import org.apache.geode.test.dunit.VM;
import org.apache.geode.test.dunit.WaitCriterion;
import org.apache.geode.test.dunit.internal.JUnit4DistributedTestCase;

public class LoginTimeOutDUnitTest extends JUnit4DistributedTestCase {
  private static final Logger logger = LogService.getLogger();

  protected static volatile boolean runTest1Ready = false;
  protected static volatile boolean runTest2Done = false;

  private static Cache cache;
  private static String tblName;

  private static String readFile(String filename) throws IOException {
    BufferedReader br = new BufferedReader(new FileReader(filename));
    String nextLine = "";
    StringBuffer sb = new StringBuffer();
    while ((nextLine = br.readLine()) != null) {
      sb.append(nextLine);
      //
      // note:
      // BufferedReader strips the EOL character.
      //
      // sb.append(lineSep);
    }
    logger.debug("***********\n " + sb);
    return sb.toString();
  }

  private static String modifyFile(String str) throws IOException {
    String search = "<jndi-binding type=\"XAPooledDataSource\"";
    String last_search = "</jndi-binding>";
    String newDB = "newDB_" + OSProcess.getId();
    String jndi_str =
        "<jndi-binding type=\"XAPooledDataSource\" jndi-name=\"XAPooledDataSource\"          jdbc-driver-class=\"org.apache.derby.jdbc.EmbeddedDriver\" init-pool-size=\"1\" max-pool-size=\"1\" idle-timeout-seconds=\"600\" blocking-timeout-seconds=\"60\" login-timeout-seconds=\"1\" conn-pooled-datasource-class=\"org.apache.derby.jdbc.EmbeddedConnectionPoolDataSource\" xa-datasource-class=\"org.apache.derby.jdbc.EmbeddedXADataSource\" user-name=\"mitul\" password=\"83f0069202c571faf1ae6c42b4ad46030e4e31c17409e19a\" connection-url=\"jdbc:derby:"
            + newDB + ";create=true\" >";
    String config_prop = "<config-property>"
        + "<config-property-name>description</config-property-name>"
        + "<config-property-type>java.lang.String</config-property-type>"
        + "<config-property-value>hi</config-property-value>" + "</config-property>"
        + "<config-property>" + "<config-property-name>user</config-property-name>"
        + "<config-property-type>java.lang.String</config-property-type>"
        + "<config-property-value>mitul</config-property-value>" + "</config-property>"
        + "<config-property>" + "<config-property-name>password</config-property-name>"
        + "<config-property-type>java.lang.String</config-property-type>"
        + "<config-property-value>83f0069202c571faf1ae6c42b4ad46030e4e31c17409e19a</config-property-value>        "
        + "</config-property>" + "<config-property>"
        + "<config-property-name>databaseName</config-property-name>"
        + "<config-property-type>java.lang.String</config-property-type>"
        + "<config-property-value>" + newDB + "</config-property-value>" + "</config-property>\n";
    String new_str = jndi_str + config_prop;
    /*
     * String new_str = " <jndi-binding type=\"XAPooledDataSource\" jndi-name=\"XAPooledDataSource\"
     * jdbc-driver-class=\"org.apache.derby.jdbc.EmbeddedDriver\"
     * init-pool-size=\"5\" max-pool-size=\"30\" idle-timeout-seconds=\"600\"
     * blocking-timeout-seconds=\"60\" login-timeout-seconds=\"20\"
     * conn-pooled-datasource-class=\"org.apache.derby.jdbc.EmbeddedConnectionPoolDataSource\"
     * xa-datasource-class=\"org.apache.derby.jdbc.EmbeddedXADataSource\" user-name=\"mitul\"
     * password=\"83f0069202c571faf1ae6c42b4ad46030e4e31c17409e19a\"
     * connection-url=\"jdbc:derby:"+newDB+";create=true\" > <property
     * key=\"description\" value=\"hi\"/> <property key=\"databaseName\"
     * value=\""+newDB+"\"/> <property key=\"user\" value=\"mitul\"/> <property key=\"password\"
     * value=\"83f0069202c571faf1ae6c42b4ad46030e4e31c17409e19a\"/>";
     */
    int n1 = str.indexOf(search);
    logger.debug("Start Index = " + n1);
    int n2 = str.indexOf(last_search, n1);
    StringBuffer sbuff = new StringBuffer(str);
    logger.debug("END Index = " + n2);
    String modified_str = sbuff.replace(n1, n2, new_str).toString();
    return modified_str;
  }

  public static String init(String className) throws Exception {
    logger.debug("PATH11 ");
    Properties props = new Properties();
    int pid = OSProcess.getId();
    String path = File.createTempFile("dunit-cachejta_", ".xml").getAbsolutePath();
    logger.debug("PATH " + path);
    /** * Return file as string and then modify the string accordingly ** */
    String file_as_str = readFile(
        createTempFileFromResource(CacheUtils.class, "cachejta.xml")
            .getAbsolutePath());
    file_as_str = file_as_str.replaceAll("newDB", "newDB_" + pid);
    String modified_file_str = modifyFile(file_as_str);
    FileOutputStream fos = new FileOutputStream(path);
    BufferedWriter wr = new BufferedWriter(new OutputStreamWriter(fos));
    wr.write(modified_file_str);
    wr.flush();
    wr.close();
    props.setProperty(CACHE_XML_FILE, path);
    props.setProperty(MCAST_PORT, "0");
    String tableName = "";
    cache = new CacheFactory(props).create();
    if (className != null && !className.equals("")) {
      String time = new Long(System.currentTimeMillis()).toString();
      tableName = className + time;
      createTable(tableName);
    }
    tblName = tableName;
    return tableName;
  }

  public static void createTable(String tableName) throws Exception {
    Context ctx = cache.getJNDIContext();
    DataSource ds = (DataSource) ctx.lookup("java:/SimpleDataSource");
    String sql =
        "create table " + tableName + " (id integer NOT NULL, name varchar(50), CONSTRAINT "
            + tableName + "_key PRIMARY KEY(id))";
    logger.debug(sql);
    Connection conn = ds.getConnection();
    Statement sm = conn.createStatement();
    sm.execute(sql);
    sm.close();
    sm = conn.createStatement();
    for (int i = 1; i <= 10; i++) {
      sql = "insert into " + tableName + " values (" + i + ",'name" + i + "')";
      sm.addBatch(sql);
      logger.debug(sql);
    }
    sm.executeBatch();
    conn.close();
  }

  public static void destroyTable() throws Exception {
    try {
      String tableName = tblName;
      Context ctx = cache.getJNDIContext();
      DataSource ds = (DataSource) ctx.lookup("java:/SimpleDataSource");
      Connection conn = ds.getConnection();
      logger.debug(" trying to drop table: " + tableName);
      String sql = "drop table " + tableName;
      Statement sm = conn.createStatement();
      sm.execute(sql);
      conn.close();
    } catch (NamingException ne) {
      logger.debug("destroy table naming exception: " + ne);
      throw ne;
    } catch (SQLException se) {
      logger.debug("destroy table sql exception: " + se);
      throw se;
    } finally {
      closeCache();
    }
  }

  private static void closeCache() {
    try {
      if (!cache.isClosed()) {
        cache.close();
      }
    } finally {
      InternalDistributedSystem ids = InternalDistributedSystem.getAnyInstance();
      if (ids != null) {
        ids.disconnect();
      }
      cache = null;
      tblName = null;
    }
  }

  @Override
  public final void postSetUp() throws Exception {
    Host host = Host.getHost(0);
    VM vm0 = host.getVM(0);
    Object o[] = new Object[1];
    o[0] = getUniqueName();
    vm0.invoke(LoginTimeOutDUnitTest.class, "init", o);
  }

  @Override
  public final void preTearDown() throws Exception {
    Host host = Host.getHost(0);
    VM vm0 = host.getVM(0);
    try {
      vm0.invoke(() -> LoginTimeOutDUnitTest.destroyTable());
    } catch (Exception e) {
      if ((e instanceof RMIException) || (e instanceof SQLException)) {
        // sometimes we have lock timeout problems destroying the table in
        // this test
        vm0.invoke(() -> disconnectFromDS());
      }
    }
  }

  // this test and the setUp and teardown2 methods are disabled due to frequent
  // failures in CI runs. See bug #52206
  @Ignore("TODO: test is disabled due to #52206")
  @Test
  public void testLoginTimeOut() throws Exception {
    Host host = Host.getHost(0);
    VM vm0 = host.getVM(0);
    AsyncInvocation test1 = vm0.invokeAsync(() -> LoginTimeOutDUnitTest.runTest1());
    AsyncInvocation test2 = vm0.invokeAsync(() -> LoginTimeOutDUnitTest.runTest2());
    ThreadUtils.join(test2, 120 * 1000);
    if (test2.exceptionOccurred()) {
      Assert.fail("asyncObj failed", test2.getException());
    }
    ThreadUtils.join(test1, 30000);
  }

  public static void runTest1() throws Exception {
    final int MAX_CONNECTIONS = 1;
    DataSource ds = null;
    try {
      try {
        Context ctx = cache.getJNDIContext();
        ds = (DataSource) ctx.lookup("java:/XAPooledDataSource");
      } catch (NamingException e) {
        logger.debug("Naming Exception caught in lookup: " + e);
        fail("failed in naming lookup: " + e);
      } catch (Exception e) {
        logger.debug("Exception caught during naming lookup: {}", e);
        fail("failed in naming lookup: " + e);
      }
      try {
        for (int count = 0; count < MAX_CONNECTIONS; count++) {
          ds.getConnection();
        }
      } catch (Exception e) {
        logger.debug("Exception caught in runTest1: {}", e);
        fail("Exception caught in runTest1: " + e);
      }
    } finally {
      runTest1Ready = true;
    }
    logger.debug("runTest1 got all of the goodies and is now sleeping");
    WaitCriterion ev = new WaitCriterion() {
      @Override
      public boolean done() {
        return runTest2Done;
      }

      @Override
      public String description() {
        return null;
      }
    };
    GeodeAwaitility.await().untilAsserted(ev);
  }

  public static void runTest2() throws Exception {
    try {
      logger.debug("runTest2 sleeping");
      WaitCriterion ev = new WaitCriterion() {
        @Override
        public boolean done() {
          return runTest1Ready;
        }

        @Override
        public String description() {
          return null;
        }
      };
      GeodeAwaitility.await().untilAsserted(ev);

      DataSource ds = null;
      try {
        Context ctx = cache.getJNDIContext();
        ds = (DataSource) ctx.lookup("java:/XAPooledDataSource");
      } catch (NamingException e) {
        logger.debug("Exception caught during naming lookup: " + e);
        fail("failed in naming lookup: " + e);
      } catch (Exception e) {
        logger.debug("Exception caught during naming lookup: " + e);
        fail("failed in because of unhandled excpetion: " + e);
      }
      try {
        logger.debug("runTest2 about to acquire connection ");
        ds.getConnection();
        fail("expected a Login time-out exceeded");
      } catch (SQLException sqle) {
        if (sqle.getMessage().indexOf("Login time-out exceeded") == -1) {
          logger.debug("Exception caught in runTest2: {}", sqle);
          fail("failed because of unhandled exception : " + sqle);
        }
      } catch (Exception e) {
        logger.debug("Exception caught in runTest2: {}", e);
        fail("failed because of unhandled exception : " + e);
      }
    } finally {
      // allow runtest1 to exit
      runTest2Done = true;
    }
  }
}
