/*
 * Copyright (c) 1998, 2020 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).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).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).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);
    }
}
