package com.capgemini.reports.definition.r24report;

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.R24Builder;
import com.capgemini.reports.database.javabean.enumeration.ReportCriteriaEnum;
import com.capgemini.reports.execution.strategies.ImmediateExecutionStrategy;
import lombok.extern.slf4j.Slf4j;
import net.lingala.zip4j.core.ZipFile;
import net.lingala.zip4j.exception.ZipException;
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.nio.file.Files;
import java.nio.file.Path;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Properties;


@Slf4j
public class Test_R24 {
  private static final TcSession session = new TcSession();
  private SoftAssertions softAssert = new SoftAssertions();
  private static final String INPUT_FOLDER = "com.capgemini.report.location.default.input";
  private static final String SPECIFIC_INPUT_FOLDER = "r24";
  private static final String TEMPORARY_OUTPUT_FOLDER = "com.capgemini.report.location.default.output";
  private static final String SUFFIX = ".zip";
  private static final PolicyLocation XML_POLICY = PolicyLocation.make("test_policy", "/xml/policies/r24report/R24_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({"productID", "unit", "typeImpr", "language", "refFile"})
  @Test
  public void test24(String productID, String unit, String typeImpr, String language, String refFile) throws
      KurtException, IOException, ZipException {
    // Génération du rapport de test
    Map<ReportCriteriaEnum, String> data = new HashMap<>();
    data.put(ReportCriteriaEnum.PRODUCT, productID);
    data.put(ReportCriteriaEnum.UNIT, unit);
    data.put(ReportCriteriaEnum.TYPE_IMPRESSION, typeImpr);
    data.put(ReportCriteriaEnum.LANGUAGE, language);

    ExecutionR24 execution = (ExecutionR24) new R24Builder().build(data);
    new DataReportPreparatorR24().print(session, execution, new ImmediateExecutionStrategy());

    List<XSSFWorkbook> excelListRef = new ArrayList<>();
    List<XSSFWorkbook> excelListGen = new ArrayList<>();

    Path tempDirGenerated = Files.createTempDirectory("tempfilesGenerated");
    Path tempDirReferenced = Files.createTempDirectory("tempfilesReferenced");


    ZipFile sourceGen = new ZipFile(localproperties.getProperty(TEMPORARY_OUTPUT_FOLDER) + execution.getFileNameOnDisc() + SUFFIX);
    sourceGen.extractAll(tempDirGenerated.toString());

    ZipFile sourceRef = new ZipFile(localproperties.getProperty(INPUT_FOLDER) + SPECIFIC_INPUT_FOLDER + "/" + refFile);
    sourceRef.extractAll(tempDirReferenced.toString());


    for (File fileInList : tempDirReferenced.toFile().listFiles()) {
      try (FileInputStream fileInput = new FileInputStream(fileInList)) {
        excelListRef.add(new XSSFWorkbook(fileInput));
      }
    }

    for (File fileOutList : tempDirGenerated.toFile().listFiles()) {
      try (FileInputStream fileOutput = new FileInputStream(fileOutList)) {
        excelListGen.add(new XSSFWorkbook(fileOutput));
      }
    }

    softAssert.assertThat(excelListGen.size()).isEqualTo(excelListRef.size());
    for (int a = 0; a < excelListGen.size() && a < excelListRef.size(); a++) {
      if (excelListGen.get(a).getNumberOfSheets() == excelListRef.get(a).getNumberOfSheets()) {
        for (int b = 0; b < excelListGen.get(a).getNumberOfSheets(); b++) {
          XSSFSheet sheetRef = excelListRef.get(a).getSheetAt(b);
          XSSFSheet sheetGen = excelListGen.get(a).getSheetAt(b);
          DataFormatter df = new DataFormatter();
          for (int i = 1; i < sheetRef.getLastRowNum(); i++) {
            XSSFRow rowRef = sheetRef.getRow(i);
            XSSFRow rowGen = sheetGen.getRow(i);
            for (int j = 0; j < rowRef.getLastCellNum(); j++) {
              XSSFCell cellRef = rowRef.getCell(j);
              XSSFCell cellGen = rowGen.getCell(j);
              softAssert.assertThat(df.formatCellValue(cellGen)).isEqualTo(df.formatCellValue(cellRef));
            }
          }
        }
      }
    }
    softAssert.assertAll();
  }
}











