/*
 * 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;

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

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

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

import org.apache.logging.log4j.Logger;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;

import org.apache.geode.cache.Cache;
import org.apache.geode.cache.CacheFactory;
import org.apache.geode.distributed.DistributedSystem;
import org.apache.geode.distributed.internal.InternalDistributedSystem;
import org.apache.geode.logging.internal.log4j.api.LogService;

public class BlockingTimeOutJUnitTest {
  private static final Logger logger = LogService.getLogger();

  private static final int BLOCKING_TIMEOUT = 1;

  private static final int RANDOM = new Random().nextInt();

  private static Cache cache;
  private static String tblName;

  private static String readFile(String filename) throws Exception {
    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 Exception {
    String search = "<jndi-binding type=\"XAPooledDataSource\"";
    String last_search = "</jndi-binding>";
    String newDB = "newDB_" + RANDOM;
    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=\"2\" idle-timeout-seconds=\"600\" blocking-timeout-seconds=\""
            + BLOCKING_TIMEOUT
            + "\" login-timeout-seconds=\"25\" 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=\"25\"
     * 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;
  }

  @SuppressWarnings("deprecation")
  private static String init(String className) throws Exception {
    DistributedSystem ds = InternalDistributedSystem.getConnectedInstance();
    if (ds != null) {
      ds.disconnect();
    }
    logger.debug("PATH11 ");
    Properties props = new Properties();
    String path = System.getProperty("CACHEXMLFILE");
    logger.debug("PATH2 " + path);
    int pid = RANDOM;
    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");
    props.setProperty(LOCATORS, "");
    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;
  }

  private 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 the_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();
  }

  private 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() throws Exception {
    try {
      if (!cache.isClosed()) {
        cache.close();
      }
    } finally {
      InternalDistributedSystem ids = InternalDistributedSystem.getAnyInstance();
      if (ids != null) {
        ids.disconnect();
      }
      cache = null;
      tblName = null;
    }
  }

  @Before
  public void setUp() throws Exception {
    init("BlockingTimeOutJUnitTest");
  }

  @After
  public void tearDown() throws Exception {
    destroyTable();
  }

  private static void fail(String str, Throwable thr) {
    throw new AssertionError(str, thr);
  }

  @Test
  public void testBlockingTimeOut() throws Exception {
    runTest1();
    runTest2();
  }

  private void runTest1() throws Exception {
    final int MAX_CONNECTIONS = 2;
    DataSource ds = null;
    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);
      return;
    } catch (Exception e) {
      logger.debug("Exception caught during naming lookup: " + e);
      fail("failed in naming lookup: ", e);
      return;
    }
    try {
      for (int count = 0; count < MAX_CONNECTIONS; count++) {
        ds.getConnection();
      }
    } catch (SQLException e) {
      logger.debug("Success SQLException caught in runTest1: " + e);
      fail("runTest1 SQL Exception caught: ", e);
    } catch (Exception e) {
      logger.debug("Exception caught in runTest1: " + e);
      fail("Exception caught in runTest1: ", e);
      e.printStackTrace();
    }
  }

  private void runTest2() throws Exception {
    final int MAX_CONNECTIONS = 2;
    logger.debug("runTest2 sleeping");
    Thread.sleep((BLOCKING_TIMEOUT + 2) * 1000);
    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 {
      for (int count = 0; count < MAX_CONNECTIONS; count++) {
        Connection con = ds.getConnection();
        assertNotNull("Connection object is null", con);

        logger.debug("runTest2 :acquired connection #" + count);
      }
    } catch (SQLException sqle) {
      logger.debug("SQLException caught in runTest2: " + sqle);
      fail("failed because of SQL exception : ", sqle);
    } catch (Exception e) {
      logger.debug("Exception caught in runTest2: " + e);
      fail("failed because of unhandled exception : ", e);
    }
  }
}
