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

import java.lang.reflect.Method;
import java.sql.Connection;
import java.sql.SQLException;
import java.util.HashMap;
import java.util.Hashtable;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;

import javax.naming.Binding;
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NameNotFoundException;
import javax.naming.NamingEnumeration;
import javax.naming.NamingException;
import javax.naming.NoInitialContextException;
import javax.sql.DataSource;
import javax.transaction.SystemException;
import javax.transaction.TransactionManager;

import org.apache.logging.log4j.Logger;

import org.apache.geode.LogWriter;
import org.apache.geode.annotations.Immutable;
import org.apache.geode.annotations.internal.MakeNotStatic;
import org.apache.geode.annotations.internal.MutableForTesting;
import org.apache.geode.distributed.DistributedSystem;
import org.apache.geode.distributed.internal.DistributionConfig;
import org.apache.geode.internal.ClassPathLoader;
import org.apache.geode.internal.datasource.ClientConnectionFactoryWrapper;
import org.apache.geode.internal.datasource.ConfigProperty;
import org.apache.geode.internal.datasource.DataSourceCreateException;
import org.apache.geode.internal.datasource.DataSourceFactory;
import org.apache.geode.internal.datasource.GemFireTransactionDataSource;
import org.apache.geode.internal.jta.TransactionManagerImpl;
import org.apache.geode.internal.jta.TransactionUtils;
import org.apache.geode.internal.jta.UserTransactionImpl;
import org.apache.geode.internal.util.DriverJarUtil;
import org.apache.geode.logging.internal.log4j.api.LogService;

/**
 * <p>
 * Utility class for binding DataSources and Transactional resources to JNDI Tree. If there is a
 * pre-existing JNDI tree in the system, the GemFire JNDI tree is not not generated.
 * </p>
 * <p>
 * Datasources are bound to jndi tree after getting initialised. The initialisation parameters are
 * read from cache.xml.
 * </p>
 * <p>
 * If there is a pre-existing TransactionManager/UserTransaction (possible in presence of
 * application server scenerio), the GemFire TransactionManager and UserTransaction will not be
 * initialised. In that case, application server TransactionManager/UserTransaction will handle the
 * transactional activity. But even in this case the datasource element will be bound to the
 * available JNDI tree. The transactional datasource (XADataSource) will make use of available
 * TransactionManager.
 * </p>
 *
 */
public class JNDIInvoker {

  private static final Logger logger = LogService.getLogger();

  // private static boolean DEBUG = false;
  /**
   * JNDI Context, this may refer to GemFire JNDI Context or external Context, in case the external
   * JNDI tree exists.
   */
  @MakeNotStatic
  private static Context ctx;
  /**
   * transactionManager TransactionManager, this refers to GemFire TransactionManager only.
   */
  @MakeNotStatic
  private static TransactionManager transactionManager;
  // most of the following came from the javadocs at:
  // http://static.springsource.org/spring/docs/2.5.x/api/org/springframework/transaction/jta/JtaTransactionManager.html
  private static final String[][] knownJNDIManagers = {{"java:/TransactionManager", "JBoss"},
      {"java:comp/TransactionManager", "Cosminexus"}, // and many others
      {"java:appserver/TransactionManager", "GlassFish"}, {"java:pm/TransactionManager", "SunONE"},
      {"java:comp/UserTransaction", "Orion, JTOM, BEA WebLogic"},
      // not sure about the following but leaving it for backwards compat
      {"javax.transaction.TransactionManager", "BEA WebLogic"}};
  /** ************************************************* */
  /**
   * WebSphere 5.1 TransactionManagerFactory
   */
  private static final String WS_FACTORY_CLASS_5_1 =
      "com.ibm.ws.Transaction.TransactionManagerFactory";
  /**
   * WebSphere 5.0 TransactionManagerFactory
   */
  private static final String WS_FACTORY_CLASS_5_0 =
      "com.ibm.ejs.jts.jta.TransactionManagerFactory";
  /**
   * WebSphere 4.0 TransactionManagerFactory
   */
  private static final String WS_FACTORY_CLASS_4 = "com.ibm.ejs.jts.jta.JTSXA";
  /**
   * Maps data source name to the data source instance itself.
   */
  @MakeNotStatic
  private static final ConcurrentMap<String, Object> dataSourceMap = new ConcurrentHashMap<>();

  /**
   * If this system property is set to true, GemFire will not try to lookup for an existing JTA
   * transaction manager bound to JNDI context or try to bind itself as a JTA transaction manager.
   * Also region operations will <b>not</b> participate in an ongoing JTA transaction.
   */
  @MutableForTesting
  private static boolean IGNORE_JTA =
      Boolean.getBoolean(DistributionConfig.GEMFIRE_PREFIX + "ignoreJTA");

  @Immutable
  private static final DataSourceFactory dataSourceFactory = new DataSourceFactory();

  /**
   * Bind the transaction resources. Bind UserTransaction and TransactionManager.
   * <p>
   * If there is pre-existing JNDI tree in the system and TransactionManager / UserTransaction is
   * already bound, GemFire will make use of these resources, but if TransactionManager /
   * UserTransaction is not available, the GemFire TransactionManager / UserTransaction will be
   * bound to the JNDI tree.
   * </p>
   *
   */
  public static void mapTransactions(DistributedSystem distSystem) {
    try {
      TransactionUtils.setLogWriter(distSystem.getLogWriter());
      cleanup();
      if (IGNORE_JTA) {
        return;
      }
      ctx = new InitialContext();
      doTransactionLookup();
    } catch (NamingException ne) {
      LogWriter writer = TransactionUtils.getLogWriter();
      if (ne instanceof NoInitialContextException) {
        String exception =
            "JNDIInvoker::mapTransactions:: No application server context found, Starting GemFire JNDI Context Context ";
        if (writer.finerEnabled())
          writer.finer(exception);
        try {
          initializeGemFireContext();
          transactionManager = TransactionManagerImpl.getTransactionManager();
          ctx.rebind("java:/TransactionManager", transactionManager);
          if (writer.fineEnabled())
            writer.fine(
                "JNDIInvoker::mapTransactions::Bound TransactionManager to Context GemFire JNDI Tree");
          UserTransactionImpl utx = new UserTransactionImpl();
          ctx.rebind("java:/UserTransaction", utx);
          if (writer.fineEnabled())
            writer.fine(
                "JNDIInvoker::mapTransactions::Bound Transaction to Context GemFire JNDI Tree");
        } catch (NamingException ne1) {
          if (writer.infoEnabled())
            writer.info(
                "JNDIInvoker::mapTransactions::NamingException while binding TransactionManager/UserTransaction to GemFire JNDI Tree");
        } catch (SystemException se1) {
          if (writer.infoEnabled())
            writer.info(
                "JNDIInvoker::mapTransactions::SystemException while binding UserTransaction to GemFire JNDI Tree");
        }
      } else if (ne instanceof NameNotFoundException) {
        String exception =
            "JNDIInvoker::mapTransactions:: No TransactionManager associated to Application server context, trying to bind GemFire TransactionManager";
        if (writer.finerEnabled())
          writer.finer(exception);
        try {
          transactionManager = TransactionManagerImpl.getTransactionManager();
          ctx.rebind("java:/TransactionManager", transactionManager);
          if (writer.fineEnabled())
            writer.fine(
                "JNDIInvoker::mapTransactions::Bound TransactionManager to Application Server Context");
          UserTransactionImpl utx = new UserTransactionImpl();
          ctx.rebind("java:/UserTransaction", utx);
          if (writer.fineEnabled())
            writer.fine(
                "JNDIInvoker::mapTransactions::Bound UserTransaction to Application Server Context");
        } catch (NamingException ne1) {
          if (writer.infoEnabled())
            writer.info(
                "JNDIInvoker::mapTransactions::NamingException while binding TransactionManager/UserTransaction to Application Server JNDI Tree");
        } catch (SystemException se1) {
          if (writer.infoEnabled())
            writer.info(
                "JNDIInvoker::mapTransactions::SystemException while binding TransactionManager/UserTransaction to Application Server JNDI Tree");
        }
      }
    }
  }

  /*
   * Cleans all the DataSource ans its associated threads gracefully, before start of the GemFire
   * system. Also kills all of the threads associated with the TransactionManager before making it
   * null.
   */
  private static void cleanup() {
    if (transactionManager instanceof TransactionManagerImpl) {
      TransactionManagerImpl.refresh();
      // unbind and set TransactionManager to null, so as to
      // initialize TXManager correctly if the cache is being restarted
      transactionManager = null;
      try {
        if (ctx != null) {
          ctx.unbind("java:/TransactionManager");
        }
      } catch (NamingException e) {
        // ok to ignore, rebind will be tried later
      }
    }
    dataSourceMap.values().stream().forEach(JNDIInvoker::closeDataSource);
    dataSourceMap.clear();
    IGNORE_JTA = Boolean.getBoolean(DistributionConfig.GEMFIRE_PREFIX + "ignoreJTA");
  }

  private static void closeDataSource(Object dataSource) {
    if (dataSource instanceof AutoCloseable) {
      try {
        ((AutoCloseable) dataSource).close();
      } catch (Exception e) {
        if (logger.isDebugEnabled()) {
          logger.debug("Exception closing DataSource", e);
        }
      }
    }
  }

  /*
   * Helps in locating TransactionManager in presence of application server scenario. Stores the
   * value of TransactionManager for reference in GemFire system.
   */
  private static void doTransactionLookup() throws NamingException {
    Object jndiObject = null;
    LogWriter writer = TransactionUtils.getLogWriter();
    for (int i = 0; i < knownJNDIManagers.length; i++) {
      try {
        jndiObject = ctx.lookup(knownJNDIManagers[i][0]);
      } catch (NamingException e) {
        String exception = "JNDIInvoker::doTransactionLookup::Couldn't lookup ["
            + knownJNDIManagers[i][0] + " (" + knownJNDIManagers[i][1] + ")]";
        if (writer.finerEnabled())
          writer.finer(exception);
      }
      if (jndiObject instanceof TransactionManager) {
        transactionManager = (TransactionManager) jndiObject;
        String exception = "JNDIInvoker::doTransactionLookup::Found TransactionManager for "
            + knownJNDIManagers[i][1];
        if (writer.fineEnabled())
          writer.fine(exception);
        return;
      } else {
        String exception = "JNDIInvoker::doTransactionLookup::Found TransactionManager of class "
            + (jndiObject == null ? "null" : jndiObject.getClass())
            + " but is not of type javax.transaction.TransactionManager";
        if (writer.fineEnabled())
          writer.fine(exception);
      }
    }
    Class clazz;
    try {
      if (writer.finerEnabled())
        writer.finer(
            "JNDIInvoker::doTransactionLookup::Trying WebSphere 5.1: " + WS_FACTORY_CLASS_5_1);
      clazz = ClassPathLoader.getLatest().forName(WS_FACTORY_CLASS_5_1);
      if (writer.fineEnabled())
        writer
            .fine("JNDIInvoker::doTransactionLookup::Found WebSphere 5.1: " + WS_FACTORY_CLASS_5_1);
    } catch (ClassNotFoundException ex) {
      try {
        if (writer.finerEnabled())
          writer.finer(
              "JNDIInvoker::doTransactionLookup::Trying WebSphere 5.0: " + WS_FACTORY_CLASS_5_0);
        clazz = ClassPathLoader.getLatest().forName(WS_FACTORY_CLASS_5_0);
        if (writer.fineEnabled())
          writer.fine(
              "JNDIInvoker::doTransactionLookup::Found WebSphere 5.0: " + WS_FACTORY_CLASS_5_0);
      } catch (ClassNotFoundException ex2) {
        try {
          clazz = ClassPathLoader.getLatest().forName(WS_FACTORY_CLASS_4);
          String exception =
              "JNDIInvoker::doTransactionLookup::Found WebSphere 4: " + WS_FACTORY_CLASS_4;
          if (writer.fineEnabled())
            writer.fine(exception, ex);
        } catch (ClassNotFoundException ex3) {
          if (writer.finerEnabled())
            writer.finer(
                "JNDIInvoker::doTransactionLookup::Couldn't find any WebSphere TransactionManager factory class, neither for WebSphere version 5.1 nor 5.0 nor 4");
          throw new NoInitialContextException();
        }
      }
    }
    try {
      Method method = clazz.getMethod("getTransactionManager", (Class[]) null);
      transactionManager = (TransactionManager) method.invoke(null, (Object[]) null);
    } catch (Exception ex) {
      writer.warning(
          String.format(
              "JNDIInvoker::doTransactionLookup::Found WebSphere TransactionManager factory class [%s], but could not invoke its static 'getTransactionManager' method",
              clazz.getName()),
          ex);
      throw new NameNotFoundException(
          String.format(
              "JNDIInvoker::doTransactionLookup::Found WebSphere TransactionManager factory class [%s], but could not invoke its static 'getTransactionManager' method",
              new Object[] {clazz.getName()}));
    }
  }

  /**
   * Initialises the GemFire context. This is called when no external JNDI Context is found.
   *
   */
  private static void initializeGemFireContext() throws NamingException {
    Hashtable table = new Hashtable();
    table.put(Context.INITIAL_CONTEXT_FACTORY,
        "org.apache.geode.internal.jndi.InitialContextFactoryImpl");
    ctx = new InitialContext(table);
  }

  /**
   * Binds a single Datasource to the existing JNDI tree. The JNDI tree may be The Datasource
   * properties are contained in the map. The Datasource implementation class is populated based on
   * properties in the map.
   *
   * @param map contains Datasource configuration properties.
   */
  public static void mapDatasource(Map map, List<ConfigProperty> props)
      throws NamingException, DataSourceCreateException, ClassNotFoundException, SQLException,
      InstantiationException, IllegalAccessException {
    mapDatasource(map, props, dataSourceFactory, ctx);
  }

  static void mapDatasource(Map map, List<ConfigProperty> props,
      DataSourceFactory dataSourceFactory, Context context)
      throws NamingException, DataSourceCreateException, ClassNotFoundException, SQLException,
      InstantiationException, IllegalAccessException {
    String driverClassName = null;
    if (map != null) {
      driverClassName = (String) map.get("jdbc-driver-class");
      DriverJarUtil util = new DriverJarUtil();
      if (driverClassName != null) {
        util.registerDriver(driverClassName);
      }
    }

    String value = (String) map.get("type");
    String jndiName = "";
    jndiName = (String) map.get("jndi-name");
    if (value.equals("PooledDataSource")) {
      validateAndBindDataSource(context, jndiName,
          dataSourceFactory.getPooledDataSource(map, props), props);
    } else if (value.equals("XAPooledDataSource")) {
      validateAndBindDataSource(context, jndiName,
          dataSourceFactory.getTranxDataSource(map, props), props);
    } else if (value.equals("SimpleDataSource")) {
      validateAndBindDataSource(context, jndiName, dataSourceFactory.getSimpleDataSource(map),
          props);
    } else if (value.equals("ManagedDataSource")) {
      ClientConnectionFactoryWrapper wrapper = dataSourceFactory.getManagedDataSource(map, props);
      ctx.rebind("java:/" + jndiName, wrapper.getClientConnFactory());
      dataSourceMap.put(jndiName, wrapper);
      if (logger.isDebugEnabled()) {
        logger.debug("Bound java:/" + jndiName + " to Context");
      }
    } else {
      String exception = "JNDIInvoker::mapDataSource::No correct type of DataSource";
      if (logger.isDebugEnabled()) {
        logger.debug(exception);
      }
      throw new DataSourceCreateException(exception);
    }
  }

  private static void validateAndBindDataSource(Context context, String jndiName,
      DataSource dataSource, List<ConfigProperty> props)
      throws NamingException, DataSourceCreateException {
    try (Connection connection = getConnection(dataSource, props)) {
    } catch (SQLException sqlEx) {
      closeDataSource(dataSource);
      throw new DataSourceCreateException(
          "Failed to connect to \"" + jndiName + "\". See log for details", sqlEx);
    }
    context.rebind("java:/" + jndiName, dataSource);
    dataSourceMap.put(jndiName, dataSource);
    if (logger.isDebugEnabled()) {
      logger.debug("Bound java:/" + jndiName + " to Context");
    }
  }

  private static Connection getConnection(DataSource dataSource, List<ConfigProperty> props)
      throws SQLException {
    return dataSource.getConnection();
  }

  public static void unMapDatasource(String jndiName) throws NamingException {
    ctx.unbind("java:/" + jndiName);
    Object removedDataSource = dataSourceMap.remove(jndiName);
    closeDataSource(removedDataSource);
  }

  public static DataSource getDataSource(String name) {
    Object result = dataSourceMap.get(name);
    if (result instanceof DataSource) {
      return (DataSource) result;
    } else {
      return null;
    }
  }

  public static boolean isValidDataSource(String name) {
    Object dataSource = dataSourceMap.get(name);

    if (dataSource == null || (dataSource instanceof DataSource
        && !(dataSource instanceof GemFireTransactionDataSource))) {
      return true;
    }

    return false;
  }

  /**
   * @return Context the existing JNDI Context. If there is no pre-esisting JNDI Context, the
   *         GemFire JNDI Context is returned.
   */
  public static Context getJNDIContext() {
    return ctx;
  }

  /**
   * returns the GemFire TransactionManager.
   *
   */
  public static TransactionManager getTransactionManager() {
    return transactionManager;
  }

  public static int getNoOfAvailableDataSources() {
    return dataSourceMap.size();
  }

  public static Map<String, String> getBindingNamesRecursively(Context ctx) throws Exception {
    Map<String, String> result = new HashMap<>();
    NamingEnumeration<Binding> enumeration = ctx.listBindings("");

    while (enumeration.hasMore()) {
      Binding binding = enumeration.next();
      String name = binding.getName();
      String separator = name.endsWith(":") ? "" : "/";
      Object o = binding.getObject();
      if (o instanceof Context) {
        Map<String, String> innerBindings = getBindingNamesRecursively((Context) o);
        innerBindings.forEach((k, v) -> result.put(name + separator + k, v));
      } else {
        result.put(name, binding.getClassName());
      }
    }

    return result;
  }
}
