package com.capgemini.framework.common;

import com.capgemini.reports.ReportLaunchTypeEnum;
import com.capgemini.reports.database.HibernateUtil;
import com.capgemini.reports.database.javabean.DbReport;
import com.capgemini.reports.database.manager.MngReport;
import com.capgemini.reports.exceptions.NotFoundException;
import org.apache.commons.io.FileUtils;
import org.hibernate.Session;
import org.hibernate.SessionFactory;

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

/**
 * Helper used for returning the appropriate location of folder.
 */
public final class ReportFolderOutputHelper {

  /**
   * The default location of the folder which contains all the IMMEDIATE or DELAYED reports.<br>
   * This value is loaded in the reporting.properties file.
   */
  private static final String DEFAULT_LOCATION_OUTPUT = SettingsHelper.getReportLocation();
  /**
   * The specific location of the folder which contains the recent scheduled reports.<br>
   * This value is loaded in the reporting.properties file.
   */
  public static final String SCHEDULING_LOCATION_OUTPUT = SettingsHelper.getSchedulingLocation();
  /**
   * The specific location of a specific folder which have to record all the scheduled reports.<br>
   * This value is loaded in the reporting.properties file.
   */
  private static final String SCHEDULING_HISTORY_LOCATION_OUTPUT = SettingsHelper.getSchedulingHistoryLocation();

  /**
   * Private constructor.
   **/
  private ReportFolderOutputHelper() {
    // Hide constructor of utility classes
  }

  /**
   * Return the appropriate location of folder associated to the report.<br>
   * The main purpose is to separate scheduled reports's folder with the other folder.
   *
   * @param launchType {@link ReportLaunchTypeEnum} - the launch type of a report
   * @return the String location of folder
   */
  public static String getStorageFolderLocation(final ReportLaunchTypeEnum launchType) {
    if (ReportLaunchTypeEnum.SCHEDULED.equals(launchType)) {
      return SCHEDULING_LOCATION_OUTPUT;
    }
    else {
      return DEFAULT_LOCATION_OUTPUT;
    }
  }

  /**
   * Check if the report has already been launched before in database.
   *
   * @param schedulingId Long - the ID of the scheduled report
   * @return true if the report has already been launched before, else false.
   */
  public static boolean checkIfAlreadyLaunched(final Long schedulingId) {
    SessionFactory sessionFactory = HibernateUtil.getSessionFactory();
    Session session = sessionFactory.openSession();
    try {
      List<DbReport> schedulingReports = new MngReport().searchBySchedulingId(schedulingId, session);
      return schedulingReports != null && schedulingReports.size() > 1; // At least two entries
    }
    finally {
      session.close();
    }
  }

  /**
   * Delete a specific scheduled report in the scheduled output.
   *
   * @param reportFileName String - the name of the file to delete
   * @throws NotFoundException if unable to delete the file
   */
  public static void deleteScheduledReportFile(final String reportFileName) throws NotFoundException {
    deleteFile(SCHEDULING_LOCATION_OUTPUT, reportFileName);
  }

  /**
   * Delete a report from his file name in the entry folder location.
   *
   * @param folderLocation String - the folder location
   * @param reportFileName String - the name of the file to delete
   * @throws NotFoundException if unable to delete the file
   */
  private static void deleteFile(final String folderLocation, final String reportFileName) throws NotFoundException {
    File fileToDelete = new File(folderLocation + reportFileName);

    // Try to delete the file and return true if it is done
    if (!fileToDelete.delete()) {
      throw new NotFoundException("Unable to delete the file " + reportFileName + " in folder " + folderLocation);
    }
  }

  /**
   * Copy a generated scheduled report in the archive folder.<br>
   * This scheduled report should have be printed before and should be located in the scheduled output.
   *
   * @param original       the file to copy
   * @param reportFileName String - the name of the report
   * @throws IOException may occur if the copy or the creation of the file doesn't work
   */
  public static void copyToHistoryFolder(File original, final String reportFileName) throws IOException {
    File archive = new File(SCHEDULING_HISTORY_LOCATION_OUTPUT + reportFileName);
    FileUtils.copyFile(original, archive);
  }

}
