/*
 * Copyright (c) 1998, 2021 Oracle and/or its affiliates. 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:
//     Oracle - initial API and implementation from Oracle TopLink
package org.eclipse.persistence.testing.framework;

import java.util.*;

import org.eclipse.persistence.config.PersistenceUnitProperties;
import org.eclipse.persistence.exceptions.*;
import org.eclipse.persistence.logging.AbstractSessionLog;
import org.eclipse.persistence.platform.database.TimesTenPlatform;
import org.eclipse.persistence.sessions.DatabaseLogin;
import org.eclipse.persistence.sessions.DatabaseSession;
import org.eclipse.persistence.platform.database.DatabasePlatform;
import org.eclipse.persistence.sessions.Project;
import org.eclipse.persistence.sessions.Session;
import org.eclipse.persistence.testing.framework.junit.JUnitTestCaseHelper;
import org.eclipse.persistence.tools.schemaframework.*;

/**
 * Used in a test model to configure the database and session.
 * This class also store every database login that we use.
 */
public class TestSystem {
    protected DatabaseLogin login;
    public Project project;

    public Map<String, String> properties;

    /**
     * Add all of the descriptors.
     */
    public void addDescriptors(DatabaseSession session) {
        session.addDescriptors(buildDescriptors());
    }

    /**
     * Return all descriptor for the system.
     * This can be used so that subclasses do not have to add descriptors themselves.
     */
    public Vector buildDescriptors() {
        return new Vector();
    }

    /**
     * Return all tables for the system.
     * This can be used so that subclasses do not have to create the tables themselves.
     */
    public Vector buildTables() {
        return new Vector();
    }

    /**
     * Define the table creation pattern.
     */
    public void createTables() throws Exception {
        DatabaseSession session;

        session = login();
        try {
            createTables(session);
        } finally {
            session.logout();
        }
    }

    /**
     * Default method to create/recreate the database.
     * First drop constraints ignoring errors if tables did not exist.
     * Second recreate the tables.
     * Then add the constraints back.
     */
    public void createTables(DatabaseSession session) throws Exception {
        Vector tables = buildTables();
        SchemaManager schemaManager = new SchemaManager(session);
        for (Enumeration dropForeignKeyEnum = tables.elements();
                 dropForeignKeyEnum.hasMoreElements();) {
            TableDefinition table = (TableDefinition)dropForeignKeyEnum.nextElement();
            try {
                schemaManager.dropConstraints(table);
            } catch (DatabaseException exception) {
                // Ignore
            }
        }
        for (Enumeration replaceEnum = tables.elements(); replaceEnum.hasMoreElements();) {
            TableDefinition table = (TableDefinition)replaceEnum.nextElement();
            schemaManager.replaceObject(table);
        }
        for (Enumeration createForeignKeyEnum = tables.elements();
                 createForeignKeyEnum.hasMoreElements();) {
            TableDefinition table = (TableDefinition)createForeignKeyEnum.nextElement();
            schemaManager.createConstraints(table);
        }
    }

    /**
     * Return the default database login to be used.
     */
    public DatabaseLogin getLogin() {
        if (login == null) {
            loadLoginFromProperties();
        }
        return login;
    }

    /**
     * Load the default login from the test.properties file.
     * This file must be on the classpath, or system property set.
     */
    public void loadLoginFromProperties() {
        this.properties = JUnitTestCaseHelper.getDatabaseProperties();
        login = new DatabaseLogin();
        login.setDriverClassName(this.properties.get(PersistenceUnitProperties.JDBC_DRIVER));
        login.setConnectionString(this.properties.get(PersistenceUnitProperties.JDBC_URL));
        login.setUserName(this.properties.get(PersistenceUnitProperties.JDBC_USER));
        // This avoids encrypting the password, as some tests require it non-encrypted.
        login.setEncryptedPassword(this.properties.get(PersistenceUnitProperties.JDBC_PASSWORD));
        String platform = this.properties.get("eclipselink.target-database");
        if (platform != null) {
            login.setPlatformClassName(platform);
        }
    }

    /**
     * Return a connected session using the default login.
     */
    public DatabaseSession login() {
        DatabaseSession session;

        session = new Project(getLogin()).createDatabaseSession();
        addDescriptors(session);
        session.setLogLevel(AbstractSessionLog.translateStringToLoggingLevel(properties.get(PersistenceUnitProperties.LOGGING_LEVEL)));
        try {
            session.login();
        } catch (DatabaseException x) {
            if (session.getPlatform().isMySQL()) {
                AbstractSessionLog.getLog().warning("Cannot login to the database");
                // Using System.err since session log may not print out the stack trace
                x.printStackTrace(System.err);
            } else {
                throw x;
            }
        }

        return session;
    }

    /**
     * Define the database population pattern.
     */
    public void populate() throws Exception {
        DatabaseSession session;

        session = login();
        try {
            populate(session);
        } finally {
            session.logout();
        }
    }

    /**
     * Abstract method for database population.
     */
    public void populate(DatabaseSession session) throws Exception {
        // Nothing by default.
    }

    /**
     * Used for configuration during testing.
     */
    public void run(Session session) throws Exception {
        // Use old API to be able to run on 9.0.4 for perf testing.
        session.getIdentityMapAccessor().initializeIdentityMaps();
        this.addDescriptors((DatabaseSession)session);
        if (session.getDatasourceLogin().getDatasourcePlatform().isTimesTen()) {
            ((TimesTenPlatform)session.getDatasourceLogin().getDatasourcePlatform()).setSupportsForeignKeyConstraints(false);
        }
        this.createTables((DatabaseSession)session);
        this.populate((DatabaseSession)session);
        // Use old API to be able to run on 9.0.4 for perf testing.
        session.getIdentityMapAccessor().initializeIdentityMaps();
    }

    /**
     * Set the default database login to be used.
     */
    public void setLogin(DatabaseLogin login) {
        this.login = login;
    }

    /**
     * You must have MS Access installed an the MS ODBC setup to a local database.
     */
    public void useAccessJDBCODBC() {
        DatabaseLogin login = new DatabaseLogin();
        login.useAccess();
        login.setODBCDataSourceName("MSACCESS");
        setLogin(login);
    }

    /**
     * You must have the Attunity Connect driver loaded.
     */
    public void useAttunityConnect() {
        DatabaseLogin login = new DatabaseLogin(new org.eclipse.persistence.platform.database.AttunityPlatform());
        login.setDatabaseURL("mercury2;deftdpname=oracle");
        login.setDriverClassName("com.attunity.jdbc.NvDriver");
        login.setDriverURLHeader("jdbc:attconnect://");
        setLogin(login);
    }

    /**
     * You must have the Derby driver loaded.
     */
    public void useDerby() {
        DatabaseLogin login = new DatabaseLogin(new org.eclipse.persistence.platform.database.DerbyPlatform());
        login.setDriverClassName("org.apache.derby.jdbc.EmbeddedDriver");
        login.setDriverURLHeader("jdbc:derby:");
        login.setDatabaseURL("test;create=true");
        setLogin(login);
    }

    /**
     * You must have the H2 driver loaded.
     */
    public void useH2() {
        DatabaseLogin login = new DatabaseLogin(new org.eclipse.persistence.platform.database.H2Platform());
        login.setDriverClassName("org.h2.Driver");
        login.setDriverURLHeader("jdbc:h2:");
        login.setDatabaseURL("test");
        login.setUserName("sa");
        login.setPassword("");
        setLogin(login);
    }

    /**
     * You must have the Postgres driver loaded.
     */
    public void usePostgres() {
        DatabaseLogin login = new DatabaseLogin(new org.eclipse.persistence.platform.database.PostgreSQLPlatform());
        login.setDriverClassName("org.postgresql.Driver");
        login.setDriverURLHeader("jdbc:postgresql:");
        login.setDatabaseURL("//ottvm048.ca.oracle.com/toplink");
        setLogin(login);
    }

    /**
     * You must have the Universal drivers and license files loaded.
     */
    public void useDB2UniversalDriver() {
        DatabaseLogin login = new DatabaseLogin();
        login.useDB2();
        login.setDriverClassName("com.ibm.db2.jcc.DB2Driver");
        login.setDriverURLHeader("jdbc:db2://");
        login.setDatabaseURL("ottvm046.ca.oracle.com:50000/TOPLINK2");
        login.setUserName("");
        //set the encrypted password will enable toplink to use the plain text password as is
        login.setEncryptedPassword("password");
        setLogin(login);
    }

    /**
     * You must have the DataDirect drivers and oc4j.jar loaded.
     */
    public void useDB2DataDirect() {
        DatabaseLogin login = new DatabaseLogin();
        login.useDB2();
        login.setDriverClassName("com.oracle.ias.jdbc.db2.DB2Driver");
        login.setDriverURLHeader("jdbc:oracle:db2://");
        login.setDatabaseURL("tlsvrdb7.ca.oracle.com:50001;DatabaseName=TOPLINK");
        login.setUserName("");
        //set the encrypted password will enable toplink to use the plain text password as is
        login.setEncryptedPassword("password");
        setLogin(login);
    }

    /**
     * You must have DB2 client installed and the IBM JDBC driver loaded.
     */
    public void useDB2App() {
        DatabaseLogin login = new DatabaseLogin();

        //login.useDB2JDBCDriver();
        login.useDB2();
        login.setDriverClassName("COM.ibm.db2.jdbc.app.DB2Driver");
        login.setDriverURLHeader("jdbc:db2:");
        login.useStreamsForBinding();
        login.setUserName("");
        //set the encrypted password will enable toplink to use the plain text password as is
        login.setEncryptedPassword("password");
        login.setDatabaseURL("TOPLINK");
        login.useByteArrayBinding();
        setLogin(login);
    }

    /**
     * You must have the IBM JDBC driver loaded.
     */
    public void useDB2Net() {
        DatabaseLogin login = new DatabaseLogin();

        login.useDB2();
        login.setDriverClassName("COM.ibm.db2.jdbc.net.DB2Driver");
        login.setDriverURLHeader("jdbc:db2:");
        login.useStreamsForBinding();
        login.setUserName("");
        //set the encrypted password will enable toplink to use the plain text password as is
        login.setEncryptedPassword("password");
        login.setDatabaseURL("tlsvrdb7.ca.oracle.com:TOPLINK");
        login.useByteArrayBinding();
        setLogin(login);
    }

    /**
     * You must have the MySQL Connector/J JDBC driver loaded.
     * @param userName java.lang.String
     * Creation date: (03/17/05 4:50:00 PM)
     * Creator: Edwin Tang
     */
    public void useMySQL(String userName) {
        DatabaseLogin login = new DatabaseLogin();

        login.useMySQL();
        login.setDriverClassName("com.mysql.jdbc.Driver");
        login.setDriverURLHeader("jdbc:mysql:");
        login.useStreamsForBinding();
        login.setUserName(userName);
        //set the encrypted password will enable toplink to use the plain text password as is
        login.setEncryptedPassword("password");
        login.setDatabaseURL("//ottvm044.ca.oracle.com:3306/"+userName);
        login.useByteArrayBinding();
        setLogin(login);
    }

    /**
     * You must have the HSQL driver loaded.  You must have the HSQL server running.
     */
    public void useHSQL() {
        DatabaseLogin login = new DatabaseLogin(new org.eclipse.persistence.platform.database.HSQLPlatform());
        login.useHSQLDriver();
        login.setDatabaseURL("file:test");
        login.setUserName("sa");
        setLogin(login);
    }

    /**
     * You must have the Informix thin driver loaded.
     */
    public void useInformixJDBC20() {
        DatabaseLogin login = new DatabaseLogin(new org.eclipse.persistence.platform.database.InformixPlatform());
        login.useInformix();
        login.useByteArrayBinding();
        login.setDriverClassName("com.informix.jdbc.IfxDriver");
        login.setDriverURLHeader("jdbc:informix-sqli://");
        login.setDatabaseURL("mercury2:1526/toplinkj:INFORMIXSERVER=toplinkj");
        login.setUserName("informix");
        //set the encrypted password will enable toplink to use the plain text password as is
        login.setEncryptedPassword("informix");
        setLogin(login);
    }

    /**
     * You must have the Informix drivers loaded.
     */
    public void useInformix11() {
        DatabaseLogin dbLogin = new DatabaseLogin(new org.eclipse.persistence.platform.database.InformixPlatform());
        dbLogin.useInformix();
        dbLogin.setDriverClassName("com.informix.jdbc.IfxDriver");
        dbLogin.setDriverURLHeader("jdbc:informix-sqli://");
        dbLogin.setDatabaseURL("tlsvrdb6.ca.oracle.com:9088/toplink:INFORMIXSERVER=informix");
        dbLogin.setUserName("informix");
        //set the encrypted password will enable toplink to use the plain text password as is
        dbLogin.setEncryptedPassword("password");
        setLogin(dbLogin);
    }

    /**
     * This is a generic configuration, would should test this occationally to test generic drivers.
     * A "JDBC" ODBC entry must be setup, however table creation will fail for most databases, I think
     * if it is setup to DB2 table creation will pass.
     */
    public void useJDBCODBC() {
        DatabaseLogin login = new DatabaseLogin();
        login.setODBCDataSourceName("JDBC");
        setLogin(login);
    }

    /**
     * You must have the Oracle client installed and the Oracle JDBC driver loaded.
     */
    public void useOracleOCI() {
        DatabaseLogin login = new DatabaseLogin(OracleDBPlatformHelper.getInstance().getOracle9Platform());
        login.useOracleJDBCDriver();
        login.setDatabaseURL("toplink");
        login.setUserName("");
        //set the encrypted password will enable toplink to use the plain text password as is
        login.setEncryptedPassword("password");
        setLogin(login);
    }

    /**
     * You must have the MS JDBC driver for SQL Server loaded.
     */
    public void useSQLServerMSJDBC() {
        DatabaseLogin login = new DatabaseLogin();
        login.useSQLServer();
        login.setDriverClassName("com.microsoft.sqlserver.jdbc.SQLServerDriver");
        login.setDriverURLHeader("jdbc:sqlserver://");
        login.setDatabaseURL("ottvm041");
        login.setUserName("dev1");
        //set the encrypted password will enable toplink to use the plain text password as is
        login.setEncryptedPassword("password");
        login.useByteArrayBinding();
        setLogin(login);
    }

    /**
     * You must have the SQL Server and the Weblogic drivers installed.
     */
    public void useSQLServerWeblogicDBLib() {
        DatabaseLogin login = new DatabaseLogin();
        login.useWebLogicSQLServerDBLibDriver();
        login.setDatabaseURL("ottvm041");
        login.setUserName("dev1");
        //set the encrypted password will enable toplink to use the plain text password as is
        login.setEncryptedPassword("password");
        login.useByteArrayBinding();
        setLogin(login);
    }

    /**
     * You must have the DataDirect drivers and oc4j.jar loaded..
     */
    public void useSQLServerDataDirect() {
        DatabaseLogin login = new DatabaseLogin();
        login.useSQLServer();
        login.setDriverClassName("com.oracle.ias.jdbc.sqlserver.SQLServerDriver");
        login.setDriverURLHeader("jdbc:oracle:sqlserver://");
        login.setDatabaseURL("localhost\\\\ottvm041");
        login.setUserName("dev1");
        //set the encrypted password will enable toplink to use the plain text password as is
        login.setEncryptedPassword("password");
        login.useByteArrayBinding();
        setLogin(login);
    }

    /**
     * You must have the Sybase JConnect thin driver loaded.
     */
    public void useSybaseJConnect() {
        DatabaseLogin login = new DatabaseLogin();
        login.useSybase();
        login.setDriverClassName("com.sybase.jdbc3.jdbc.SybDriver");
        login.setDriverURLHeader("jdbc:sybase:Tds:");
        login.setDatabaseURL("ottvm031.ca.oracle.com:5000/qa2");
        login.setUserName("qa2");
        //set the encrypted password will enable toplink to use the plain text password as is
        login.setEncryptedPassword("password");
        setLogin(login);
    }

    /**
     * You must have the DataDirect drivers and oc4j.jar loaded.
     */
    public void useSybaseDataDirect() {
        DatabaseLogin login = new DatabaseLogin();
        login.useSybase();
        login.setDriverClassName("com.oracle.ias.jdbc.sybase.SybaseDriver");
        login.setDriverURLHeader("jdbc:oracle:sybase://");
        login.setDatabaseURL("ottvm031.ca.oracle.com:5000/qa2");
        login.setUserName("qa2");
        //set the encrypted password will enable toplink to use the plain text password as is
        login.setEncryptedPassword("password");
        setLogin(login);
    }

    /**
     * You must have the Oracle thin driver loaded.
     * @param userName java.lang.String
     * Creation date: (12/7/00 4:03:00 PM)
     * Creator: Edwin Tang
     */
    public void useOracleThin(String databaseURL, String userName, String password) {
        DatabasePlatform platform = null;
        try{
            Class platformClass = Class.forName("org.eclipse.persistence.platform.database.oracle.Oracle9Platform");
            platform = (DatabasePlatform)platformClass.getConstructor().newInstance();
        } catch (Exception e){
            platform = new org.eclipse.persistence.platform.database.OraclePlatform();
        }
        DatabaseLogin login = new DatabaseLogin(platform);

        login.useOracleThinJDBCDriver();
        login.setDatabaseURL(databaseURL);
        login.setUserName(userName);
        //set the encrypted password will enable toplink to use the plain text password as is
        login.setEncryptedPassword(password);
        setLogin(login);
    }

    /**
     * You must have the Oracle 8 thin driver loaded.
     * @param userName java.lang.String
     * Creation date: (12/7/00 4:03:00 PM)
     * Creator: Praba Vijayaratnam
     */
    public void useOracle8Thin(String databaseURL, String userName, String password) {
        DatabasePlatform platform = null;
        try{
            Class platformClass = Class.forName("org.eclipse.persistence.platform.database.oracle.Oracle8Platform");
            platform = (DatabasePlatform)platformClass.getConstructor().newInstance();
        } catch (Exception e){
            platform = new org.eclipse.persistence.platform.database.OraclePlatform();
        }
        DatabaseLogin login = new DatabaseLogin(platform);
        login.useOracleThinJDBCDriver();
        login.setDatabaseURL(databaseURL);
        login.setUserName(userName);
        //set the encrypted password will enable toplink to use the plain text password as is
        login.setEncryptedPassword(password);
        setLogin(login);
    }

    /**
    * You must have DB2 installed with the IBM DB2 ODBC driver setup as "DB2".
    */
    public void useDB2JDBCODBC() {
        DatabaseLogin login = new DatabaseLogin();
        login.useDB2();
        login.setODBCDataSourceName("DB2");
        login.setUserName("");
        login.setTableQualifier("");
        //set the encrypted password will enable toplink to use the plain text password as is
        login.setEncryptedPassword("password");
        setLogin(login);
    }

    /**
     * You must have DB2 installed with a TopLink database created and the IBM JDBC driver loaded.
     */
    public void useDB2JDBC() {
        DatabaseLogin login = new DatabaseLogin();
        login.useDB2JDBCDriver();
        login.useByteArrayBinding();
        login.useStreamsForBinding();
        login.setUserName("");
        //set the encrypted password will enable toplink to use the plain text password as is
        login.setEncryptedPassword("password");
        login.setDatabaseURL("TOPLINK");
        setLogin(login);
    }

    /**
    * You must have the SQL Server and the Weblogic drivers installed.
    */
    public void useSQLServerWeblogicThin() {
        DatabaseLogin login = new DatabaseLogin();
        login.useSQLServer();
        login.useWebLogicSQLServerDriver();
        login.setODBCDataSourceName("localhost");
        login.setUserName("");
        //set the encrypted password will enable toplink to use the plain text password as is
        login.setEncryptedPassword("password");
        login.useByteArrayBinding();
        setLogin(login);
    }

    /**
     * You must have the Sybase JConnect thin driver loaded.
     */
    public void useSybaseJConnect50() {
        DatabaseLogin login = new DatabaseLogin();
        login.setDriverClassName("");

        login.setDatabaseURL("tlsvrdb1.ca.oracle.com:5000/COREDEV1");
        login.setUserName("");
        //set the encrypted password will enable toplink to use the plain text password as is
        login.setEncryptedPassword("password");
        setLogin(login);
    }

    /**
     * You must have the Sybase client installed and the Weblogic JDBC driver loaded.
     */
    public void useSybaseWeblogicDBLib() {
        DatabaseLogin login = new DatabaseLogin();
        login.useWebLogicSybaseDBLibDriver();
        login.setDatabaseURL("");
        login.setUserName("");
        //set the encrypted password will enable toplink to use the plain text password as is
        login.setEncryptedPassword("password");
        setLogin(login);
    }

    /**
     * You must have the SQL Server and the i-net jdbc driver for java 2 installed. This will run on TM2.
     */
    public void useSQLServerThin() {
        DatabaseLogin login = new DatabaseLogin();
        login.useSQLServer();
        login.useINetSQLServerDriver();
        login.setODBCDataSourceName("localhost");
        login.setUserName("");
        //set the encrypted password will enable toplink to use the plain text password as is
        login.setEncryptedPassword("password");
        login.useByteArrayBinding();
        setLogin(login);
    }

    /**
     * You must have the TimesTen JDBC driver loaded.
     * @param userName java.lang.String
     * Creation date: (11/10/05 4:55:00 PM)
     * Creator: Edwin Tang
     */
    public void useTimesTen(String userName) {
        DatabaseLogin login = new DatabaseLogin();
        try {
            login.usePlatform((org.eclipse.persistence.internal.databaseaccess.DatabasePlatform)Class.forName("org.eclipse.persistence.platform.database.TimesTenPlatform").getConstructor().newInstance());
        } catch (Exception e) {}
        login.setDriverClassName("com.timesten.jdbc.TimesTenDriver");
        login.setDriverURLHeader("jdbc:timesten:client:");
        login.useStreamsForBinding();
        login.setUserName(userName);
        //set the encrypted password will enable toplink to use the plain text password as is
        login.setEncryptedPassword("password");
        login.setDatabaseURL(userName);
        login.useByteArrayBinding();
        setLogin(login);
    }

    /**
     * You must have the Symfoware JDBC driver loaded.
     */
    public void useSymfowareRDB2_TCP() {
        DatabaseLogin login = new DatabaseLogin();
        try {
            login.usePlatform((org.eclipse.persistence.internal.databaseaccess.DatabasePlatform)Class.forName("org.eclipse.persistence.platform.database.SymfowarePlatform").getConstructor().newInstance());
        } catch (Exception e) {
            e.printStackTrace();
        }
        login.setDriverClassName("com.fujitsu.symfoware.jdbc.SYMDriver");
        login.setDriverURLHeader("jdbc:symford:");
        // codeselect setting reduces garbled characters when DB and client's
        // character encoding settings do not match
        login.setDatabaseURL("TESTDB");
        //set the encrypted password will enable toplink to use the plain text password as is
        login.setEncryptedPassword("password");
        setLogin(login);
    }
}
