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

import org.eclipse.persistence.platform.database.DatabasePlatform;
import org.eclipse.persistence.sessions.*;
import org.eclipse.persistence.testing.tests.TestRunModel;

/**
 * Run a test model, test suite or test case from the DOS prompt.
 *
 * @author Edwin Tang
 */
public class PromptTestRunner {
    public static final String DB_DRIVER_KEY = "db.driver";
    public static final String DB_DRIVER_DEFAULT = "oracle.jdbc.OracleDriver";
    public static final String DB_URL_KEY = "db.url";
    public static final String DB_URL_DEFAULT = "jdbc:oracle:thin:@localhost:1521:ORCL";
    public static final String DB_USER_KEY = "db.user";
    public static final String DB_USER_DEFAULT = "scott";
    public static final String DB_PWD_KEY = "db.pwd";
    public static final String DB_PWD_DEFAULT = "tiger";
    public static final String DB_PLATFORM_KEY = "db.platform";
    public static final String DB_PLATFORM_DEFAULT = "org.eclipse.persistence.platform.database.OraclePlatform";
    public static final String LOGGING_LEVEL_KEY = "eclipselink.logging.level";
    public static final String LOGGING_LEVEL_DEFAULT = "info";

    protected static final String TEST_MODEL_FLAG = "testmodel=";
    protected static final String TEST_ENTITY_FLAG = "testentity=";
    protected static final String REGRESSION_LOG_FLAG = "regressionlog=";
    protected static final String USE_NATIVE_SQL_FLAG = "usenativesql=";
    protected static final String SAVE_RESULTS_FLAG = "saveresults=";
    protected static final String CREATE_DB_CONNECTION_FLAG = "createdbconnection=";

    private String databasePlatform;
    private String driverClass;
    private String databaseURL;
    private String username;
    private String password;

    private Writer regressionLog;
    private boolean shouldHandleErrors = true;
    private boolean useNativeSQL = false;
    private boolean saveResults = false;
    private boolean createDbConnection = true;
    private TestModel testModel;
    private TestEntity testEntity;
    private DatabaseSession session;
    private int sessionLogLevel;

    /**
    * Util method to log output.
    */
    public static void log(String str) {
        System.out.println(str);
    }

    /**
     * This method creates a new DatabaseLogin and DatabaseSession and logs in to the database.
     */
    public void login() {
        getLoginProperties();
        DatabaseLogin login = new org.eclipse.persistence.sessions.DatabaseLogin();
        try {
            login.usePlatform((DatabasePlatform)Class.forName(this.databasePlatform).getConstructor().newInstance());
        } catch (Exception e) {
            e.printStackTrace();
            printUsageAndExit();
        }
        login.setDriverClassName(this.driverClass);
        login.setConnectionString(this.databaseURL);
        login.setUserName(this.username);
        login.setEncryptedPassword(this.password);
        if (useNativeSQL) {
            login.useNativeSQL();
        }
        this.session = new org.eclipse.persistence.sessions.Project(login).createDatabaseSession();
        this.session.setLogLevel(this.sessionLogLevel);
        this.session.setLog(new OutputStreamWriter(System.out));
        this.session.login();
    }

    /**
     * This method logs out of the database.
     */
    public void logout() {
        this.session.logout();
    }

    public static void main(String[] args) {
        new PromptTestRunner().run(args);
        System.exit(0);
    }

    /**
     * This method logs in to the specified database and executes the specified test model.
     */
    public void run(String[] argv) {
        if ((argv.length < 1) || (argv.length > 5)) {
            this.printUsageAndExit();
        }
        for (int i = 0; i < argv.length; i++) {
            this.processArguments(argv[i]);
        }

        try {
            if (createDbConnection) {
                login();
            }
            TestExecutor executor = new TestExecutor();
            executor.setSession(this.session);
            if (this.regressionLog != null) {
                executor.setRegressionLog(this.regressionLog);
            }
            if (shouldHandleErrors) {
                executor.handleErrors();
            }
            if ((testEntity != null) && (testModel != null)) {
                this.testModel.setExecutor(executor);
                this.testModel.setupEntity();
                executor.execute(testEntity);
                executor.logResultForTestEntity(this.testEntity);
                executor.logRegressionResultForTestEntity(this.testEntity);
            } else if (testModel != null) {
                if (createDbConnection) {
                    LoadBuildSystem.loadBuild.userName = testModel.getName();
                    LoadBuildSystem.loadBuild.loginChoice = executor.getSession().getLogin().getConnectionString();
                }
                executor.runTest(this.testModel);
                if (createDbConnection) {
                    if (saveResults && (LoadBuildSystem.loadBuild != null) && (!LoadBuildSystem.loadBuild.isEmpty())) {
                        LoadBuildSystem loadBuildSystem = new LoadBuildSystem();
                        loadBuildSystem.saveLoadBuild();
                    }
                }
            } else {
                log("\nNo test model specified.");
            }
            if (createDbConnection) {
                logout();
            }
        } catch (Throwable exception) {
            exception.printStackTrace();
        }
    }

    protected void processArguments(String arg) {
        if (arg.startsWith(TEST_MODEL_FLAG)) {
            String testModelName = arg.substring(TEST_MODEL_FLAG.length());
            if (testModelName.toLowerCase().equals("lightrunalltestmodel")) {
                this.testModel = TestRunModel.buildLRGTestModel();
            } else {
                try {
                    this.testModel = (TestModel)(Class.forName(testModelName).getConstructor().newInstance());
                } catch (Exception e) {
                    e.printStackTrace();
                    printUsageAndExit();
                }
            }
        } else if (arg.startsWith(TEST_ENTITY_FLAG)) {
            String testEntityName = arg.substring(TEST_ENTITY_FLAG.length());
            try {
                this.testEntity = (TestEntity)Class.forName(testEntityName).getConstructor().newInstance();
            } catch (Exception e) {
                e.printStackTrace();
                printUsageAndExit();
            }
        } else if (arg.startsWith(REGRESSION_LOG_FLAG)) {
            String regressionLogFileName = arg.substring(REGRESSION_LOG_FLAG.length());
            try {
                this.regressionLog = new FileWriter(regressionLogFileName, true);
            } catch (IOException e) {
                log("\nWrite regression log file " + regressionLogFileName + " error!");
                System.exit(1);
            }
        } else if (arg.startsWith(USE_NATIVE_SQL_FLAG)) {
            useNativeSQL = arg.substring(USE_NATIVE_SQL_FLAG.length()).equalsIgnoreCase("true");
        } else if (arg.startsWith(SAVE_RESULTS_FLAG)) {
            saveResults = arg.substring(SAVE_RESULTS_FLAG.length()).equalsIgnoreCase("true");
        } else if (arg.startsWith(CREATE_DB_CONNECTION_FLAG)) {
            createDbConnection = !(arg.substring(CREATE_DB_CONNECTION_FLAG.length()).equalsIgnoreCase("false"));
        } else {
            log("Invalid argument: " + arg);
            this.printUsageAndExit();
        }
    }

    public void printUsageAndExit() {
        log("\nUsage:\t java <Java VM arguments> org.eclipse.persistence.testing.framework.PromptTestRunner " + TEST_MODEL_FLAG + "<testModel> [" + TEST_ENTITY_FLAG + "<testEntity> " + REGRESSION_LOG_FLAG + "<regressionLogFile> " + USE_NATIVE_SQL_FLAG + "<shouldUseNativeSQL> " + SAVE_RESULTS_FLAG + "<shouldSaveResults>]" + CREATE_DB_CONNECTION_FLAG + "<shouldCreateDbConnection>]");
        log("\n\tWhere:");
        log("\n\t<Java VM arguments>: Required, specifies Database Login properties");
        log("\n\t<testModel>: Required, specifies test model class name");
        log("\n\t" + "<testEntity>: Optional, specifies test entity class name(test model, test suite or test case). " + "When specified, the runner will setup the test model and run the test entity only");
        log("\n\t" + "<regressionLogFile>: Optional, specifies file name of regression log, in which there is no label-related info.");
        log("\n\t<shouldUseNativeSQL>: Optional, valid values are 'true' and 'false', default value is 'false'.");
        log("\n\t<shouldSaveResults>: Optional, valid values are 'true' and 'false', default value is 'false'.");
        log("\n\t<shouldCreateDbConnection>: Optional, valid values are 'true' and 'false', default value is 'true'.");
        log("\n\t" + "Example:");
        log("\n\t" + "java");
        log("\n\t\t-D" + DB_DRIVER_KEY + "=" + DB_DRIVER_DEFAULT);
        log("\n\t\t-D" + DB_URL_KEY + "=" + DB_URL_DEFAULT);
        log("\n\t\t-D" + DB_USER_KEY + "=" + DB_USER_DEFAULT);
        log("\n\t\t-D" + DB_PWD_KEY + "=" + DB_PWD_DEFAULT);
        log("\n\t\t-D" + DB_PLATFORM_KEY + "=" + DB_PLATFORM_DEFAULT);
        log("\n\t\t-D" + LOGGING_LEVEL_KEY + "=" + LOGGING_LEVEL_DEFAULT);
        log("\n\t" + "org.eclipse.persistence.testing.Testframework.PromptTestRunner");
        log("\n\t\t" + TEST_MODEL_FLAG + "org.eclipse.persistence.testing.FeatureTests.FeatureTestModel ");
        log("\n\t\t" + TEST_ENTITY_FLAG + "org.eclipse.persistence.testing.FeatureTests.OptimisticLockingDeleteRowTest ");
        log("\n\t\t" + REGRESSION_LOG_FLAG + "C:\\temp\\OptimisticLockingDeleteRowTest.log");
        System.exit(0);
    }

    public void getLoginProperties() {
        //set sessionLogLevel - value used in setSessionLogLevel(int), default is INFO (5)
        String loggingLevel = System.getProperty(LOGGING_LEVEL_KEY, LOGGING_LEVEL_DEFAULT);
        if (loggingLevel.equalsIgnoreCase("off")) {
            this.sessionLogLevel = 8;
        }
        else if (loggingLevel.equalsIgnoreCase("severe")) {
            this.sessionLogLevel = 7;
        }
        else if (loggingLevel.equalsIgnoreCase("warning")) {
            this.sessionLogLevel = 6;
        }
        else if (loggingLevel.equalsIgnoreCase("config")) {
            this.sessionLogLevel = 4;
        }
        else if (loggingLevel.equalsIgnoreCase("fine")) {
            this.sessionLogLevel = 3;
        }
        else if (loggingLevel.equalsIgnoreCase("finer")) {
            this.sessionLogLevel = 2;
        }
        else if (loggingLevel.equalsIgnoreCase("finest")) {
            this.sessionLogLevel = 1;
        }
        else if (loggingLevel.equalsIgnoreCase("all")) {
            this.sessionLogLevel = 0;
        }
        else {
            this.sessionLogLevel = 5;
        }
        this.driverClass = System.getProperty(DB_DRIVER_KEY, DB_DRIVER_DEFAULT);
        this.databaseURL = System.getProperty(DB_URL_KEY, DB_URL_DEFAULT);
        this.username = System.getProperty(DB_USER_KEY, DB_USER_DEFAULT);
        this.password = System.getProperty(DB_PWD_KEY, DB_PWD_DEFAULT);
        this.databasePlatform = System.getProperty(DB_PLATFORM_KEY, DB_PLATFORM_DEFAULT);
    }
}
