/*
 * Copyright (c) 2005, 2021 Oracle and/or its affiliates. All rights reserved.
 * Copyright (c) 2005, 2015 SAP. All rights reserved.
 *
 * This program and the accompanying materials are made available under the
 * terms of the Eclipse Public License v. 2.0 which is available at
 * http://www.eclipse.org/legal/epl-2.0,
 * or the Eclipse Distribution License v. 1.0 which is available at
 * http://www.eclipse.org/org/documents/edl-v10.php.
 *
 * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
 */

// Contributors:
//     SAP - initial API and implementation

package org.eclipse.persistence.testing.framework.wdf;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.sql.Connection;
import java.sql.DatabaseMetaData;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Hashtable;
import java.util.Locale;
import java.util.Map;
import java.util.Properties;
import java.util.Set;

import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;
import jakarta.persistence.EntityManager;
import jakarta.persistence.EntityManagerFactory;
import jakarta.persistence.LockModeType;
import jakarta.persistence.Persistence;
import javax.sql.DataSource;

import org.eclipse.persistence.config.PersistenceUnitProperties;
import org.eclipse.persistence.testing.framework.junit.JUnitTestCaseHelper;
import org.eclipse.persistence.testing.framework.server.JEEPlatform;
import org.eclipse.persistence.testing.framework.server.ServerPlatform;
import org.eclipse.persistence.testing.tests.feature.TestDataSource;
import org.junit.Assert;
import org.junit.Before;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized.Parameters;

@SuppressWarnings("unchecked")
@RunWith(SkipBugzillaTestRunner.class)
public abstract class AbstractBaseTest {

    // /** System variable to set the tests to run on the server. */
    // public static final String RUN_ON_SERVER = "server.run";
    //
    private static Map<String, EntityManagerFactory> emfNamedPersistenceUnits = new Hashtable<String, EntityManagerFactory>();

    /** Determine if the test is running on a JEE server, or in JSE. */

    private static ServerPlatform serverPlatform;

    private final JPAEnvironment environment;
    private final String puName;
    private final static DataSource dataSource;
    protected final static Map EMF_PROPERTIES;

    private static boolean seesJPA2 = (LockModeType.values().length > 2);

    static {
        final DataSource aDataSource;

        if (!ServerInfoHolder.isOnServer()) {
            Map<String, String> properties = JUnitTestCaseHelper.getDatabaseProperties();
            String driver = properties.get(PersistenceUnitProperties.JDBC_DRIVER);
            String url = properties.get(PersistenceUnitProperties.JDBC_URL);
            String user = properties.get(PersistenceUnitProperties.JDBC_USER);
            String password = properties.get(PersistenceUnitProperties.JDBC_PASSWORD);

            Properties userPasswd = new Properties();
            userPasswd.put("user", user);
            userPasswd.put("password", password);

            DataSource ds = new TestDataSource(driver, url, userPasswd);
            aDataSource = new PooledDataSource(ds);

        } else {
            Context context;
            try {
                context = new InitialContext();
                aDataSource = (DataSource) context.lookup(ServerInfoHolder.getDataSourceName());
            } catch (NamingException e) {
                throw new RuntimeException(e);
            }
        }
        dataSource = aDataSource;
        EMF_PROPERTIES = new HashMap();
        EMF_PROPERTIES.put("delimited-identifiers", "true");
        EMF_PROPERTIES.put(PersistenceUnitProperties.NON_JTA_DATASOURCE, dataSource);
    }

    public AbstractBaseTest(String name) {
        environment = new ResourceLocalEnvironment();
        puName = name;
    }

    protected final JPAEnvironment getEnvironment() {
        return environment;
    }

    @Parameters
    public static void parameters() {

    }

    final class ResourceLocalEnvironment implements JPAEnvironment {

        @Override
        public void beginTransaction(EntityManager em) {
            em.getTransaction().begin();
        }

        @Override
        public void commitTransaction(EntityManager em) {
            em.getTransaction().commit();
        }

        @Override
        public void commitTransactionAndClear(EntityManager em) {
            try {
                commitTransaction(em);
            } finally {
                em.clear();
            }
        }

        @Override
        public EntityManagerFactory createNewEntityManagerFactory() throws NamingException {
            AbstractBaseTest.closeEntityManagerFactory(puName);
            return Persistence.createEntityManagerFactory(puName, EMF_PROPERTIES);
        }

        @Override
        public EntityManager getEntityManager() {
            return getEntityManagerFactory().createEntityManager();
            // return AbstractBaseTest.createEntityManager(puName,
            // EMF_PROPERTIES);
        }

        @Override
        public EntityManagerFactory getEntityManagerFactory() {
            return AbstractBaseTest.getEntityManagerFactory(puName, EMF_PROPERTIES);
        }

        @Override
        public boolean isTransactionActive(EntityManager em) {
            return em.getTransaction().isActive();
        }

        @Override
        public boolean isTransactionMarkedForRollback(EntityManager em) {
            return em.getTransaction().getRollbackOnly();
        }

        @Override
        public void markTransactionForRollback(EntityManager em) {
            em.getTransaction().setRollbackOnly();
        }

        @Override
        public void rollbackTransaction(EntityManager em) {
            em.getTransaction().rollback();
        }

        @Override
        public void rollbackTransactionAndClear(EntityManager em) {
            try {
                rollbackTransaction(em);
            } finally {
                em.clear();
            }
        }

        @Override
        public boolean usesExtendedPC() {
            return true;
        }

        @Override
        public DataSource getDataSource() {
            return AbstractBaseTest.this.getDataSource();
        }

        @Override
        public EntityManagerFactory createNewEntityManagerFactory(Map properties) throws NamingException {
            Map mergedProperties = new HashMap();
            mergedProperties.putAll(EMF_PROPERTIES);
            mergedProperties.putAll(properties);

            AbstractBaseTest.closeEntityManagerFactory(puName);
            return Persistence.createEntityManagerFactory(puName, mergedProperties);
        }

        @Override
        public Object getPropertyValue(EntityManager em, String key) {
            Object delegate = em.getDelegate();
            Method getEntityManagerFactoryMethod;
            try {
                getEntityManagerFactoryMethod = delegate.getClass().getMethod("getEntityManagerFactory");
                Object emf = getEntityManagerFactoryMethod.invoke(delegate);

                Method getPropertiesMethod = emf.getClass().getMethod("getProperties");
                @SuppressWarnings("rawtypes")
                Map map = (Map) getPropertiesMethod.invoke(emf);

                return map.get(key);
            } catch (NoSuchMethodException e) {
                throw new RuntimeException(e);
            } catch (IllegalArgumentException e) {
                throw new RuntimeException(e);
            } catch (IllegalAccessException e) {
                throw new RuntimeException(e);
            } catch (InvocationTargetException e) {
                throw new RuntimeException(e);
            }

        }

        @Override
        public void evict(EntityManager em, Class<?> clazz) {
            Object delegate = em.getDelegate();
            Method getEntityManagerFactoryMethod;
            try {
                getEntityManagerFactoryMethod = delegate.getClass().getMethod("getEntityManagerFactory");
                Object emf = getEntityManagerFactoryMethod.invoke(delegate);

                Method getCacheMethod = emf.getClass().getMethod("getCache");
                Object cache =  getCacheMethod.invoke(emf);

                Method evictClassMethod = cache.getClass().getMethod("evict", Class.class);

                evictClassMethod.invoke(cache, clazz);
            } catch (NoSuchMethodException e) {
                throw new RuntimeException(e);
            } catch (IllegalArgumentException e) {
                throw new RuntimeException(e);
            } catch (IllegalAccessException e) {
                throw new RuntimeException(e);
            } catch (InvocationTargetException e) {
                throw new RuntimeException(e);
            }
        }

        @Override
        public void evictAll(EntityManager em) {
            Object delegate = em.getDelegate();
            Method getEntityManagerFactoryMethod;
            try {
                getEntityManagerFactoryMethod = delegate.getClass().getMethod("getEntityManagerFactory");
                Object emf = getEntityManagerFactoryMethod.invoke(delegate);

                Method getCacheMethod = emf.getClass().getMethod("getCache");
                Object cache =  getCacheMethod.invoke(emf);

                Method evictClassMethod = cache.getClass().getMethod("evictAll");

                evictClassMethod.invoke(cache);
            } catch (NoSuchMethodException e) {
                throw new RuntimeException(e);
            } catch (IllegalArgumentException e) {
                throw new RuntimeException(e);
            } catch (IllegalAccessException e) {
                throw new RuntimeException(e);
            } catch (InvocationTargetException e) {
                throw new RuntimeException(e);
            }
        }

    }

    final class JTATxScopedEnvironment implements JPAEnvironment {

        @Override
        public void beginTransaction(EntityManager em) {
            AbstractBaseTest.this.beginTransaction(em);
        }

        @Override
        public void commitTransaction(EntityManager em) {
            AbstractBaseTest.this.commitTransaction(em);
        }

        @Override
        public void commitTransactionAndClear(EntityManager em) {
            try {
                commitTransaction(em);
            } finally {
                em.clear();
            }
        }

        @Override
        public EntityManagerFactory createNewEntityManagerFactory() throws NamingException {
            AbstractBaseTest.closeEntityManagerFactory(puName);
            return Persistence.createEntityManagerFactory(puName, EMF_PROPERTIES);
        }

        @Override
        public EntityManager getEntityManager() {
            return AbstractBaseTest.createEntityManager(puName, EMF_PROPERTIES);
        }

        @Override
        public EntityManagerFactory getEntityManagerFactory() {
            return AbstractBaseTest.getEntityManagerFactory(puName, EMF_PROPERTIES);
        }

        @Override
        public boolean isTransactionActive(EntityManager em) {
            return AbstractBaseTest.this.isTransactionActive(em);
        }

        @Override
        public boolean isTransactionMarkedForRollback(EntityManager em) {
            return AbstractBaseTest.this.getRollbackOnly(em);
        }

        @Override
        public void markTransactionForRollback(EntityManager em) {
            throw new UnsupportedOperationException();
        }

        @Override
        public void rollbackTransaction(EntityManager em) {
            AbstractBaseTest.this.rollbackTransaction(em);
        }

        @Override
        public void rollbackTransactionAndClear(EntityManager em) {
            try {
                rollbackTransaction(em);
            } finally {
                em.clear();
            }
        }

        @Override
        public boolean usesExtendedPC() {
            return true;
        }

        @Override
        public DataSource getDataSource() {
            return AbstractBaseTest.this.getDataSource();
        }

        @Override
        public EntityManagerFactory createNewEntityManagerFactory(Map<String, Object> properties) throws NamingException {
            throw new UnsupportedOperationException();
        }

        @Override
        public Object getPropertyValue(EntityManager em, String key) {
            throw new UnsupportedOperationException();
        }

        @Override
        public void evict(EntityManager em, Class<?> clazz) {
            throw new UnsupportedOperationException();
        }

        @Override
        public void evictAll(EntityManager em) {
            throw new UnsupportedOperationException();
        }

    }

    public DataSource getDataSource() {
        return dataSource;
    }

    final public void closeEntityManager(EntityManager em) {
        if (!em.isOpen()) {
            return;
        }
        if (environment.isTransactionActive(em)/*
                                                * ||environment.
                                                * isTransactionMarkedForRollback
                                                * (em)
                                                */) { // FIXME discuss if tx is
            // active if marked for
            // rollback
            environment.rollbackTransaction(em);
        }
        // // close application-managed entity manager
        // if (!(getEnvironment() instanceof JTASharedPCEnvironment)) {
        // em.close(); FIXME
        // }
    }

    protected static void verify(boolean condition, String string) {
        Assert.assertTrue(string, condition);
    }

    protected static void verifyEquals(Object expected, Object actual, String msg) {
        Assert.assertEquals(msg, expected, actual);
    }

    protected final void flop(final String msg) {
        Assert.fail(msg);
    }

    abstract protected String[] getClearableTableNames();

    @Before
    public void clearAllTablesAndSetup() throws SQLException {
        clearAllTables();

        setup();
    }

    protected void clearAllTables() throws SQLException {
        Connection conn = getDataSource().getConnection();
        try {
            conn.setAutoCommit(false);

            Set<String> existingTables = new HashSet<String>();
            DatabaseMetaData metaData = conn.getMetaData();
            String schemaPattern = null;
            if (metaData.getDriverName().toLowerCase().contains("oracle")) {
                schemaPattern = metaData.getUserName().toUpperCase();
            }
            ResultSet rs = metaData.getTables(null, schemaPattern, "TMP_%", null);
            try {
                while (rs.next()) {
                    existingTables.add(rs.getString("TABLE_NAME").toUpperCase(Locale.ENGLISH));
                }
            } finally {
                rs.close();
            }

            Statement statement = conn.createStatement();
            try {
                if (existingTables.contains("TMP_CASC_NODE")) {
                    statement.executeUpdate("update TMP_CASC_NODE set PARENT = null");
                }
                if (existingTables.contains("TMP_NODE")) {
                    statement.executeUpdate("update TMP_NODE set PARENT = null");
                }
                if (existingTables.contains("TMP_COP")) {
                    statement.executeUpdate("update TMP_COP set PARTNER_ID = null");
                }
                if (existingTables.contains("TMP_UCOFFICE_CUBICLE")) {
                    statement.executeUpdate("delete from TMP_UCOFFICE_CUBICLE");
                    existingTables.remove("TMP_UCOFFICE_CUBICLE");
                }
                for (String name : getClearableTableNames()) {
                    if (existingTables.contains(name.toUpperCase(Locale.ENGLISH))) {
                        statement.executeUpdate("delete from " + name);
                    }
                }
            } catch (SQLException ex) {
                System.err.println(ex.getMessage());
                throw ex;
            } finally {
                statement.close();
            }
            conn.commit();
        } finally {
            conn.close();
        }

        // TODO evictAll

    }

    /**
     * intended to be overwritten by subclasses
     */
    protected void setup() throws SQLException {

    }

    public static final <T extends Serializable> T serializeDeserialize(T serializable) throws IOException, ClassNotFoundException {
        ByteArrayOutputStream out = new ByteArrayOutputStream();
        ObjectOutputStream objectOutputStream = new ObjectOutputStream(out);
        try {
            objectOutputStream.writeObject(serializable);
        } finally {
            objectOutputStream.close();
        }
        ByteArrayInputStream in = new ByteArrayInputStream(out.toByteArray());
        return (T) new ObjectInputStream(in).readObject();
    }

    public static boolean isInsideEngine() {
        return false;
    }

    /**
     * Checks whether the given throwable is of type
     * java.lang.IllegalStateException, or otherwise if the throwable contains a
     * java.lang.IllegalStateException somewhere in the cause stack.
     *
     * @param e
     *            The throwable to check
     * @return <code>true</code> if the throwable is instance of or caused by
     *         java.lang.IllegalStateException
     */
    protected final boolean checkForIllegalStateException(Throwable e) {
        boolean contained = false;
        while (e != null) {
            if (e instanceof IllegalStateException) {
                contained = true;
                break;
            }
            e = e.getCause();
        }
        return contained;
    }

    /**
     * Checks whether the given throwable is of type java.sql.SQLException, or
     * otherwise if the throwable contains a java.sql.SQLException somewhere in
     * the cause stack.
     *
     * @param e
     *            The throwable to check
     * @return <code>true</code> if the throwable is instance of or caused by
     *         java.sql.SQLException
     */
    protected final boolean checkForSQLException(Throwable e) {
        boolean contained = false;
        while (e != null) {
            if (e instanceof SQLException) {
                contained = true;
                break;
            }
            e = e.getCause();
        }
        return contained;
    }

    /**
     * Return if the transaction is active. This allows the same code to be used
     * on the server where JTA is used.
     */
    public boolean isTransactionActive(EntityManager entityManager) {
        if (ServerInfoHolder.isOnServer()) {
            return getServerPlatform().isTransactionActive();
        } else {
            return entityManager.getTransaction().isActive();
        }
    }

    /**
     * Return if the transaction is roll back only. This allows the same code to
     * be used on the server where JTA is used.
     */
    public boolean getRollbackOnly(EntityManager entityManager) {
        if (ServerInfoHolder.isOnServer()) {
            return getServerPlatform().getRollbackOnly();
        } else {
            return entityManager.getTransaction().getRollbackOnly();
        }
    }

    /**
     * Begin a transaction on the entity manager. This allows the same code to
     * be used on the server where JTA is used.
     */
    public void beginTransaction(EntityManager entityManager) {
        if (ServerInfoHolder.isOnServer()) {
            getServerPlatform().beginTransaction();
        } else {
            entityManager.getTransaction().begin();
        }
    }

    /**
     * Commit a transaction on the entity manager. This allows the same code to
     * be used on the server where JTA is used.
     */
    public void commitTransaction(EntityManager entityManager) {
        if (ServerInfoHolder.isOnServer()) {
            getServerPlatform().commitTransaction();
        } else {
            entityManager.getTransaction().commit();
        }
    }

    /**
     * Rollback a transaction on the entity manager. This allows the same code
     * to be used on the server where JTA is used.
     */
    public void rollbackTransaction(EntityManager entityManager) {
        if (ServerInfoHolder.isOnServer()) {
            getServerPlatform().rollbackTransaction();
        } else {
            entityManager.getTransaction().rollback();
        }
    }

    /**
     * Return the server platform if running in JEE.
     */
    public static ServerPlatform getServerPlatform() {
        if (serverPlatform == null) {
            serverPlatform = new JEEPlatform();
        }
        return serverPlatform;
    }

    /**
     * Create a new entity manager for the "default" persistence unit. If in JEE
     * this will create or return the active managed entity manager.
     */
    public static EntityManager createEntityManager() {
        if (ServerInfoHolder.isOnServer()) {
            return getServerPlatform().getEntityManager("default");
        } else {
            return getEntityManagerFactory().createEntityManager();
        }
    }

    /**
     * Create a new entity manager for the persistence unit using the
     * properties. The properties will only be used the first time this entity
     * manager is accessed. If in JEE this will create or return the active
     * managed entity manager.
     */
    public static EntityManager createEntityManager(String persistenceUnitName, Map<String, String> properties) {
        if (ServerInfoHolder.isOnServer()) {
            return getServerPlatform().getEntityManager(persistenceUnitName);
        } else {
            return getEntityManagerFactory(persistenceUnitName, properties).createEntityManager();
        }
    }

    public static EntityManagerFactory getEntityManagerFactory(String persistenceUnitName) {
        return getEntityManagerFactory(persistenceUnitName, JUnitTestCaseHelper.getDatabaseProperties());
    }

    public static EntityManagerFactory getEntityManagerFactory(String persistenceUnitName, Map<String, String> properties) {
        if (ServerInfoHolder.isOnServer()) {
            return getServerPlatform().getEntityManagerFactory(persistenceUnitName);
        } else {
            EntityManagerFactory emfNamedPersistenceUnit = emfNamedPersistenceUnits.get(persistenceUnitName);
            if (emfNamedPersistenceUnit == null) {
                emfNamedPersistenceUnit = Persistence.createEntityManagerFactory(persistenceUnitName, properties);
                emfNamedPersistenceUnits.put(persistenceUnitName, emfNamedPersistenceUnit);
            }
            return emfNamedPersistenceUnit;
        }
    }

    public static EntityManagerFactory getEntityManagerFactory() {
        return getEntityManagerFactory("default");
    }

    public static void closeEntityManagerFactory() {
        closeEntityManagerFactory("default");
    }

    public static void closeEntityManagerFactory(String persistenceUnitName) {
        EntityManagerFactory emfNamedPersistenceUnit = emfNamedPersistenceUnits.get(persistenceUnitName);
        if (emfNamedPersistenceUnit != null) {
            if (emfNamedPersistenceUnit.isOpen()) {
                emfNamedPersistenceUnit.close();
            }
            emfNamedPersistenceUnits.remove(persistenceUnitName);
        }
    }

    public static boolean seesJPA2() {
        return seesJPA2;
    }

    public static Map<String, String> getTestProperties() {
        if (ServerInfoHolder.isOnServer()) {
            return ServerInfoHolder.getTestProperties();
        } else {
            return JUnitTestCaseHelper.getDatabaseProperties();
        }

    }
}
