package com.capgemini.framework.db;

import com.capgemini.framework.common.FileHelper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.IOException;

/**
 * Utility class for running SQL queries from an SQL file.
 **/
public final class SqlHelper {
  private static final Logger log = LoggerFactory.getLogger(SqlHelper.class);

  private SqlHelper() {
    /* Constructor of helper classes must be private */
  }

  /**
   * Load a set of SQL queries from a text file.
   *
   * @param aDbManager Database manager for executing SQL queries
   * @param aFilePath  File path for the loaded SQL file
   * @return True when all executed queries have been successfully run
   **/
  public static boolean runSqlFile(DbManager aDbManager, String aFilePath) throws IOException {

    /* Check file existence */
    if (!FileHelper.fileExist(aFilePath)) {
      log.error("SQL file does not exist: {}", aFilePath);
      return false;
    }

    /* Extract the SQL file content */
    String theFileContent = FileHelper.read(aFilePath);

    /* Separate each query */
    String[] theQueryArray = theFileContent.split(";\n");

    return runSqlFile(aDbManager, aFilePath, theQueryArray);
  }

  /**
   * Load a set of SQL queries from a text file.
   *
   * @param aDbManager  Database manager for executing SQL queries
   * @param aFilePath   File path for the loaded SQL file
   * @param aQueryArray List of SQL queries executed
   * @return True when all executed queries have been successfully run
   **/
  public static boolean runSqlFile(DbManager aDbManager, String aFilePath, String[] aQueryArray) {

    boolean isSuccess = true;
    int successQueryCount = 0;

    /* Browse SQL queries from file */
    for (String currentQuery : aQueryArray) {

      /* Check if current query could be managed by loader */
      String currentUnformatedQuery = unformatQuery(currentQuery);
      if (currentUnformatedQuery.isEmpty()) {
        continue;
      }

      /* Run the SQL query */
      if (aDbManager.executeQuery(currentUnformatedQuery)) {
        successQueryCount++;
      }
      else {
        isSuccess = false;
      }
    }

    /* Log correct queries */
    if (successQueryCount > 0) {
      log.debug("{} queries have been executed successfully from file: {}", successQueryCount, aFilePath);
    }

    return isSuccess;
  }

  /**
   * Clean the special characters used for indentation in the query.
   *
   * @param aQueryValue Original query (with pretty print format)
   * @return Cleaned query
   **/
  private static String unformatQuery(String aQueryValue) {

    String theUnformatedQuery = aQueryValue;

    /* Delete "pretty print" */
    theUnformatedQuery = theUnformatedQuery.replace("\n", " ").replace("\r", "").replace("\t", " ");

    /* Delete comments */
    theUnformatedQuery = theUnformatedQuery.replaceAll("/\\*.*?\\*/", "").trim();

    /* Ignore query with only "COMMIT" instruction */
    if ("COMMIT".equalsIgnoreCase(theUnformatedQuery)) {
      theUnformatedQuery = "";
    }

    return theUnformatedQuery;
  }
}
