package com.capgemini.framework.deployment;

import com.capgemini.framework.common.FileHelper;
import com.capgemini.framework.common.FolderHelper;
import com.capgemini.framework.db.DbManager;
import com.capgemini.framework.db.SqlHelper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.File;
import java.io.IOException;
import java.util.List;

/**
 * Main class of executable JAR.
 **/
public class Install {
  private static final Logger log = LoggerFactory.getLogger(Install.class);
  private String homeDir;
  private DeployProperties deployProperties;

  /**
   * Main entry point of executable JAR.
   *
   * @param args Command line arguments
   */
  public static void main(String[] args) {
    log.info("Start installation");
    log.info("==================");

    boolean isSuccess = true;
    int theStatus = 0;
    try {
      Install theInstaller = new Install();

      /* Check that the execution mode has been selected */
      isSuccess = theInstaller.checkEnvironment();
      if (isSuccess) {
        isSuccess = theInstaller.runSqlExec();
      }
    }
    catch (Exception e) {
      log.error("Unexpected error occurred", e);
    }
    finally {
      if (!isSuccess) {
        log.info("Installation status: FAILED");
        theStatus = 1;
      }
      else {
        log.info("Installation status: SUCCESS");
      }
      log.info("===============================");
    }
    System.exit(theStatus);
  }

  /**
   * Check if a environment variable is set.
   *
   * @return True when variable is set
   */
  private static boolean checkEnvVar() {
    boolean isSet = true;
    String theEnvValue = System.getenv("DEPLOY_TOOL_HOME");
    if (theEnvValue == null) {
      isSet = false;
    }
    return isSet;
  }

  /**
   * Load SQL files which are in the "sql" sub-folder.
   *
   * @return True when all the SQL queries have been executed successfully
   **/
  private boolean runSqlExec() throws IOException {

    boolean isSuccess = true;

    /* Retrieve database parameters from properties */
    String url = deployProperties.getString("database.url");
    String theLogin = deployProperties.getString("database.schema.login");
    String thePass = deployProperties.getString("database.schema.password");

    /* Instantiate database connector */
    DbManager theDbManager = new DbManager(url, theLogin, thePass);

    /* Browse PL/SQL folder and load each SQL file */
    File thePlSqlFolder = new File(homeDir + "/plsql");
    List<String> theDirList = FolderHelper.dirList(thePlSqlFolder, "sql");
    for (String currentFile : theDirList) {
      String currentFilePath = homeDir + "/plsql/" + currentFile;
      String currentFileContent = FileHelper.read(currentFilePath);
      isSuccess &= SqlHelper.runSqlFile(theDbManager, currentFilePath, new String[]{currentFileContent});
    }

    /* Browse SQL folder and load each SQL file */
    File theSqlFolder = new File(homeDir + "/sql");
    theDirList = FolderHelper.dirList(theSqlFolder, "sql");
    for (String currentFile : theDirList) {
      isSuccess &= SqlHelper.runSqlFile(theDbManager, homeDir + "/sql/" + currentFile);
    }

    return isSuccess;
  }

  /**
   * Run all prerequisite checks for verifying the environment setup.
   **/
  private boolean checkEnvironment() {
    /* Check environment */
    if (!checkEnvVar()) {
      log.error("The environment variable DEPLOY_TOOL_HOME must be set");
      return false;
    }
    homeDir = getEnvDir();
    String propFilePath = homeDir + "/db.properties";
    if (!FileHelper.fileExist(propFilePath)) {
      log.error("The property file for installation is missing: {}", propFilePath);
      return false;
    }

    /* Call the properties loader when all prerequisites checks have been done. */
    deployProperties = new DeployProperties(propFilePath);

        return true;
    }

    /**
     * Get directory path and replace backslash separator to slash separator.
     **/
    private String getEnvDir() {
        String theDirPath = System.getenv("DEPLOY_TOOL_HOME");
        return theDirPath.replace("\\", "/");
    }
}
