FileReaderUtil.java

package com.sintia.ffl.admin.optique.specifique.isea.utils;

import com.sintia.ffl.admin.optique.specifique.isea.models.*;
import com.sintia.ffl.admin.optique.specifique.isea.reporter.ChargementReporter;
import lombok.extern.slf4j.Slf4j;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import org.springframework.web.multipart.MultipartFile;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.StandardCopyOption;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.function.Function;
import java.util.stream.Collectors;

@Component
@Slf4j
public class FileReaderUtil {
	
	@Value("${local.resources.directory.isea}")
	private String localDirectory;
	
	@Autowired
	private ChargementReporter chargementReporter;
	
	private static final Logger LOGGER = LoggerFactory.getLogger(FileReaderUtil.class);
	
	private static final String SEPARATOR = ";" ;
	
	public static final String PAS_D_ENREGISTREMENT_TYPE_DANS_LE_FICHIER = "Pas d'enregistrement de type {} dans le fichier.";
	
	
	public void saveCatalogFile(MultipartFile file){
		try {
			String separator = System.getProperty("file.separator");
			DateFormat df = new SimpleDateFormat("yyyyMMddhhmmss");
			String localPathFileName = localDirectory + separator + file.getName()+"-"+ df.format(new Date());
			Path folder = Paths.get(localPathFileName);
			Path fileToSavePath = Files.createFile(folder);
			Files.copy(file.getInputStream(), fileToSavePath, StandardCopyOption.REPLACE_EXISTING);

		} catch (Exception e) {
			log.error("Error while saving File Catalogue Isea Csv - Error {} ", e.getMessage());
		}
	}
	
	public File getFile(){
		
		String localPath = localDirectory;
		Path folder = Paths.get(localPath);
		try {
			Optional<Path> lastFile = Files.list(folder)
					.filter(f -> !Files.isDirectory(f))
					.max(Comparator.comparingLong(f -> f.toFile().lastModified()));
			return lastFile.get().toFile();
		} catch (Exception e) {
			chargementReporter.addError("File not found " +e.getMessage());
		}
		return null;
	}
	
	private LigneOptimeyes mapToItemMap (String lineFile , int lineNumber) {
		String[] values = lineFile.split(SEPARATOR,2);

		return new LigneOptimeyes(Integer.valueOf(values[0]) ,  Arrays.asList(values[1].replace("\"","").split(SEPARATOR)) , lineNumber );
	};
	
	public List<LigneOptimeyes> processcsvfile (File file) {
		if(file != null) {
			if (file.isFile()) {
				try {
					InputStream inputFS = new FileInputStream(file);
					BufferedReader br = new BufferedReader(new InputStreamReader(inputFS));
					AtomicInteger lineNumber = new AtomicInteger(1);
					List<LigneOptimeyes> inputList = br.lines().map(line -> mapToItemMap(line, lineNumber.getAndIncrement())).collect(Collectors.toList());
					br.close();
					return inputList;
				} catch (IOException e) {
					LOGGER.error("Erreur lecture Fichier");
				}
			}

		} else
			LOGGER.error("File not found");
		
		return null;
	}

	public List<FabricantCSV> getListFabricants (List<LigneOptimeyes> lignesFichierImporte){
		List<FabricantCSV> listFabricants = new ArrayList<>();
		for(LigneOptimeyes line : lignesFichierImporte) {
			if (line.getCode() == 01) {
				setFabricants(listFabricants, line);
			}
		}
		return listFabricants;
	}

	public List<FournisseurCSV> getListfournisseurs(List<LigneOptimeyes> lignesFichierImporte){
		List<FournisseurCSV> listFournisseurs = new ArrayList<>();
		for(LigneOptimeyes line : lignesFichierImporte) {
			if (line.getCode() == 02) {
				setFournisseurs(listFournisseurs, line);
			}
		}
		return listFournisseurs;
	}

	public List<VerreCSV> getListverres(List<LigneOptimeyes> lignesFichierImporte){
		List<VerreCSV> listverres = new ArrayList<>();
		for(LigneOptimeyes line : lignesFichierImporte) {
			if (line.getCode() == 11) {
				setVerres(listverres, line);
			}
		}
		return listverres;
	}

	public List<SupplementCSV> getListsupplements(List<LigneOptimeyes> lignesFichierImporte){
		List<SupplementCSV> listsupplements = new ArrayList<>();
		for(LigneOptimeyes line : lignesFichierImporte) {
			if (line.getCode() == 12) {
				setSupplements(listsupplements,  line);
			}
		}
		return listsupplements;
	}

	public List<VerreSupplementAssoCSV> getListverreSupplementAssos(List<LigneOptimeyes> lignesFichierImporte){
		List<VerreSupplementAssoCSV> listverreSupplementAssos = new ArrayList<>();
		for(LigneOptimeyes line : lignesFichierImporte) {
			if (line.getCode() == 17) {
				setSupplementVerreAssos(listverreSupplementAssos, line);
			}
		}
		return listverreSupplementAssos;
	}


	
	/**
	 * Mapping to SupplementVerreAssos
	 * @param listverreSupplementAssos
	 * @param line
	 */
	private void setSupplementVerreAssos(List<VerreSupplementAssoCSV> listverreSupplementAssos,
										 LigneOptimeyes line) {
		try {
			VerreSupplementAssoCSV verreSupplementAssoCSV = new VerreSupplementAssoCSV();
			verreSupplementAssoCSV.setCodeFabricant(line.getContent().get(0));
			verreSupplementAssoCSV.setCodeFournisseur(line.getContent().get(1));
			verreSupplementAssoCSV.setCodeSupplement(line.getContent().get(2));
			verreSupplementAssoCSV.setCodeVerre(line.getContent().get(3));
			verreSupplementAssoCSV.setSupplementObligatoire(line.getContent().get(5));
			verreSupplementAssoCSV.setSupplementInclus(line.getContent().get(6));
			verreSupplementAssoCSV.setTypeSupplement(line.getContent().get(7));
			verreSupplementAssoCSV.setAction(line.getContent().get(25));
			listverreSupplementAssos.add(verreSupplementAssoCSV);
		} catch (Exception e) {
			String errorLog = "Erreur de lecture (ligne ignorée) : il manque probablement un ';' à la ligne "  + line.getCode() + " : " + e.getMessage();
			LOGGER.error(errorLog);
			chargementReporter.addError(errorLog);
		}
	}
	
	/**
	 * Mapping to Supplements
	 * @param listsupplements
	 * @param line
	 */
	private void setSupplements(List<SupplementCSV> listsupplements, LigneOptimeyes line) {

		try {
			SupplementCSV supplementCSV = new SupplementCSV();
			supplementCSV.setCodeFabricant(line.getContent().get(0));
			supplementCSV.setCodeFournisseur(line.getContent().get(1));
			supplementCSV.setCodeSupplement(line.getContent().get(2));
			supplementCSV.setNomSupplement(line.getContent().get(3));
			supplementCSV.setTypeSupplement(line.getContent().get(5));
			supplementCSV.setAntiReflet(line.getContent().get(7));
			supplementCSV.setTeinte(line.getContent().get(8));
			supplementCSV.setPolymerisation(line.getContent().get(9));
			supplementCSV.setDurci(line.getContent().get(10));
			supplementCSV.setAntiSalissure(line.getContent().get(11));
			supplementCSV.setUv(line.getContent().get(12));
			supplementCSV.setControle(line.getContent().get(13));
			supplementCSV.setAction(line.getContent().get(21));
			listsupplements.add(supplementCSV);
		} catch (Exception e) {
			String errorLog = "Erreur de lecture (ligne ignorée) : il manque probablement un ';' à la ligne "  + line.getLineNumber() + " : " + e.getMessage();
			LOGGER.error(errorLog);
			chargementReporter.addError(errorLog);
		}

	}
	
	/**
	 * Mapping to Verres
	 * @param listverres
	 * @param line
	 */
	private void setVerres(List<VerreCSV> listverres, LigneOptimeyes line) {
		try{
			VerreCSV verreCSV = new VerreCSV();
			verreCSV.setCodeFabricant(line.getContent().get(0));
			verreCSV.setCodeFournisseur(line.getContent().get(1));
			verreCSV.setCodeVerre(line.getContent().get(2));
			verreCSV.setNomVerre(line.getContent().get(3));
			verreCSV.setGeometrie(line.getContent().get(5));
			verreCSV.setMatiere(line.getContent().get(6));
			verreCSV.setTypeSurface(line.getContent().get(7));
			verreCSV.setPhotochromique(line.getContent().get(8));
			verreCSV.setRefraction(line.getContent().get(9));
			verreCSV.setTeinte(line.getContent().get(15));
			verreCSV.setAction(line.getContent().get(42));
			verreCSV.setClasseVerre(line.getContent().get(43));
			listverres.add(verreCSV);
		} catch (Exception e) {
			String errorLog = "Erreur de lecture (ligne ignorée) : il manque probablement un ';' à la ligne "  + line.getCode() + " : " + e.getMessage();
			LOGGER.error(errorLog);
			chargementReporter.addError(errorLog);
		}
	}
	
	/**
	 * Mapping to Fabricants
	 * @param listFabricants
	 * @param line
	 */
	private void setFabricants(List<FabricantCSV> listFabricants,  LigneOptimeyes line) {
		try {
			FabricantCSV fabricantCSV = new FabricantCSV();
			fabricantCSV.setCodeFabricant(line.getContent().get(0));
			fabricantCSV.setNomFabricant(line.getContent().get(1));
			fabricantCSV.setAction(line.getContent().get(2));
			listFabricants.add(fabricantCSV);
		} catch (Exception e) {
			String errorLog = "Erreur de lecture (ligne ignorée) : il manque probablement un ';' à la ligne " + line.getLineNumber() + " : " + e.getMessage();
			LOGGER.error(errorLog);
			chargementReporter.addError(errorLog);
		}
	}
	
	/**
	 * Mapping to Fournisseurs
	 * @param listfournisseurs
	 * @param line
	 */
	private void setFournisseurs(List<FournisseurCSV> listfournisseurs, LigneOptimeyes line) {
		try {
			FournisseurCSV fournisseurCSV = new FournisseurCSV();
			fournisseurCSV.setCodeFournisseur(line.getContent().get(0));
			fournisseurCSV.setNomFournisseur(line.getContent().get(1));
			fournisseurCSV.setAction(line.getContent().get(2));
			listfournisseurs.add(fournisseurCSV);
		} catch (Exception e) {
			String errorLog = "Erreur de lecture (ligne ignorée) : il manque probablement un ';' à la ligne " + line.getLineNumber() + " : " + e.getMessage();
			LOGGER.error(errorLog);
			chargementReporter.addError(errorLog);
		}
	}
	
	/**
	 * Verification Structure du fichier entrant
	 * @param file
	 * @return
	 */
	public List<String> getFileStructureErrors(File file){
		List<LigneOptimeyes> fileLines = processcsvfile(file);
		List<String> fileStructureErrors = new ArrayList<>();

		if(!fileLines.stream().anyMatch(line -> line.getCode() == 99)) {
			fileStructureErrors.add("Pas de fin d'enregistrement dans le fichier (identifiant : 99)");
		}
		if(!fileLines.stream().anyMatch(line -> line.getCode() == 00)) {
			fileStructureErrors.add("Pas d'entete dans le fichier (identifiant : 00)");
		}
		if(!fileLines.stream().anyMatch(line -> line.getCode() == 11)) {
			fileStructureErrors.add( PAS_D_ENREGISTREMENT_TYPE_DANS_LE_FICHIER.replace("{}" , "type verre (identifiant : 11)"));
		}
		if(!fileLines.stream().anyMatch(line -> line.getCode() == 12)) {
			fileStructureErrors.add(PAS_D_ENREGISTREMENT_TYPE_DANS_LE_FICHIER.replace("{}" , "supplement verre (identifiant : 12)"));
		}
		if(!fileLines.stream().anyMatch(line -> line.getCode() == 17)) {
			fileStructureErrors.add(PAS_D_ENREGISTREMENT_TYPE_DANS_LE_FICHIER.replace("{}" ,"association verre/supplement (identifiant : 17)"));
		}
		if(!fileLines.stream().anyMatch(line -> line.getCode() == 01)) {
			fileStructureErrors.add(PAS_D_ENREGISTREMENT_TYPE_DANS_LE_FICHIER.replace("{}" , "fabricant (identifiant : 01)"));
		}
		if(!fileLines.stream().anyMatch(line -> line.getCode() == 02)) {
			fileStructureErrors.add(PAS_D_ENREGISTREMENT_TYPE_DANS_LE_FICHIER.replace("{}" , "fournisseur (identifiant : 02)"));
		}
		return fileStructureErrors;
	}

}