package com.capgemini.reports.definition.r13report;

import com.capgemini.framework.teamcenter.authent.TcSession;
import com.capgemini.framework.teamcenter.exceptions.InvalidConfigurationException;
import com.capgemini.framework.teamcenter.exceptions.KurtException;
import com.capgemini.framework.teamcenter.exceptions.NoTeamcenterConnectionException;
import com.capgemini.framework.teamcenter.policies.PolicyLocation;
import com.capgemini.reports.builder.R13CrBuilder;
import com.capgemini.reports.database.javabean.enumeration.ReportCriteriaEnum;
import com.capgemini.reports.definition.r13report.datapreparator.DataReportPreparatorR13CR;
import com.capgemini.reports.definition.r13report.execution.ExecutionR13CR;
import com.capgemini.reports.execution.strategies.ImmediateExecutionStrategy;
import lombok.extern.slf4j.Slf4j;
import org.apache.poi.ss.usermodel.DataFormatter;
import org.apache.poi.xssf.usermodel.XSSFCell;
import org.apache.poi.xssf.usermodel.XSSFRow;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.assertj.core.api.SoftAssertions;
import org.testng.annotations.AfterClass;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.Parameters;
import org.testng.annotations.Test;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;


@Slf4j
public class Test_CrR13 {
  private static final TcSession session = new TcSession();
  private SoftAssertions softAssert = new SoftAssertions();
  // Dossier parent du fichier de référence
  private static final String INPUT_FOLDER = "com.capgemini.report.location.default.input";
  // Sous-dossier du fichier de référence
  private static final String SPECIFIC_INPUT_FOLDER = "r13";
  // Dossier de stockage temporaire des fichiers générés initialement
  private static final String TEMPORARY_OUTPUT_FOLDER = "com.capgemini.report.location.default.output";
  // Type de fichier traités
  private static final String SUFFIX = ".xlsx";
  private static final PolicyLocation XML_POLICY = PolicyLocation.make("test_policy", "/xml/policies/r13report/R13_policy_full.xml");
  private Properties localproperties;


  @BeforeClass
  public void login() throws NoTeamcenterConnectionException, InvalidConfigurationException, IOException {
    session.login();
    session.setObjectPropPolicy(XML_POLICY);
    localproperties = new Properties();
    localproperties.load(getClass().getResourceAsStream("/reporting.properties"));
  }

  @AfterClass
  public void logout() {
    session.close();
  }

  //@BeforeMethod
  //TODO : Supprimer xls files dans Generated, checker Tempfile TempDirectory


  @Parameters({"objectType", "beginDate", "endDate", "refFile"})
  @Test
  public void test13_cr(String objectType, String beginDate, String endDate, String refFile) throws KurtException, IOException {

    // Génération du rapport de test
    Map<ReportCriteriaEnum, String> data = new HashMap<>();
    data.put(ReportCriteriaEnum.TYPE_OBJET, objectType);
    data.put(ReportCriteriaEnum.DATE_DEBUT, beginDate);
    data.put(ReportCriteriaEnum.DATE_FIN, endDate);

    ExecutionR13CR execution = new R13CrBuilder().build(data);
    new DataReportPreparatorR13CR().print(session, execution, new ImmediateExecutionStrategy());

    try (FileInputStream fileInput = new FileInputStream(new File((localproperties.getProperty(INPUT_FOLDER)) + SPECIFIC_INPUT_FOLDER + "/" + refFile));
         FileInputStream fileOutput = new FileInputStream(new File(localproperties.getProperty(TEMPORARY_OUTPUT_FOLDER) + execution.getFileNameOnDisc() + SUFFIX))) {


      XSSFWorkbook workbookRef = new XSSFWorkbook(fileInput);
      XSSFWorkbook workbookGen = new XSSFWorkbook(fileOutput);
      DataFormatter df = new DataFormatter();

      softAssert.assertThat(workbookRef.getNumberOfSheets()).isEqualTo(workbookGen.getNumberOfSheets());
      for (int h = 0; h < workbookGen.getNumberOfSheets() && h < workbookRef.getNumberOfSheets(); h++) {
        // Un fichier excel est composé de plusieurs feuilles, on y accède de la manière suivante
        XSSFSheet sheetRef = workbookRef.getSheetAt(h);
        XSSFSheet sheetGen = workbookGen.getSheetAt(h);
        for (int i = 0; i <= sheetRef.getLastRowNum(); i++) {
          XSSFRow rowRef = sheetRef.getRow(i);
          XSSFRow rowGen = sheetGen.getRow(i);
          for (int j = 0; j <= 34; j++) {
            XSSFCell cellRef = rowRef.getCell(j);
            XSSFCell cellGen = rowGen.getCell(j);
            softAssert.assertThat(df.formatCellValue(cellGen)).isEqualTo(df.formatCellValue(cellRef));
          }
        }
      }
    }
    softAssert.assertAll();
  }
}
