package com.iqser.red.service.persistence.management.v1.processor.dataexchange.zipreaders;

import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.nio.charset.StandardCharsets;
import java.util.List;
import java.util.stream.Collectors;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.iqser.red.commons.jackson.ObjectMapperFactory;
import com.iqser.red.service.persistence.management.v1.processor.exception.BadRequestException;
import com.iqser.red.service.persistence.management.v1.processor.dataexchange.models.EntityTypeImportModel;
import com.iqser.red.service.persistence.management.v1.processor.dataexchange.ExportFilename;
import com.iqser.red.service.persistence.service.v1.api.shared.model.dossiertemplate.type.Type;

import lombok.AccessLevel;
import lombok.Getter;
import lombok.RequiredArgsConstructor;
import lombok.SneakyThrows;
import lombok.experimental.FieldDefaults;
import lombok.extern.slf4j.Slf4j;

@Slf4j
@Getter
@RequiredArgsConstructor
@FieldDefaults(makeFinal = true, level = AccessLevel.PRIVATE)
public class EntityTypeArchiveReader {

    ObjectMapper mapper = ObjectMapperFactory.create();

    EntityTypeImportModel entityTypeImportModel = new EntityTypeImportModel();


    @SneakyThrows
    public boolean handleZipEntryData(ZipEntryData zipEntryData) {

        if (zipEntryData.entry().getName().contains(ExportFilename.DOSSIER_TYPE.getFilename())) {
            Type type = mapper.readValue(zipEntryData.data(), Type.class);
            entityTypeImportModel.getTypes().add(type);
        } else if (zipEntryData.entry().getName().contains(ExportFilename.ENTRIES.getFilename())) {
            List<String> entries = this.readEntries(zipEntryData.data());
            entityTypeImportModel.getEntries().put(zipEntryData.getParentFolder(), entries);
        } else if (zipEntryData.entry().getName().contains(ExportFilename.FALSE_POSITIVES.getFilename())) {
            List<String> falsePositives = this.readEntries(zipEntryData.data());
            entityTypeImportModel.getFalsePositives().put(zipEntryData.getParentFolder(), falsePositives);
        } else if (zipEntryData.entry().getName().contains(ExportFilename.FALSE_RECOMMENDATION.getFilename())) {
            List<String> falseRecommendations = this.readEntries(zipEntryData.data());
            entityTypeImportModel.getFalseRecommendations().put(zipEntryData.getParentFolder(), falseRecommendations);
        } else if (zipEntryData.entry().getName().contains(ExportFilename.DELETED_ENTRIES.getFilename())) {
            List<String> entries = this.readEntries(zipEntryData.data());
            entityTypeImportModel.getDeletedEntries().put(zipEntryData.getParentFolder(), entries);
        } else if (zipEntryData.entry().getName().contains(ExportFilename.DELETED_FALSE_POSITIVES.getFilename())) {
            List<String> falsePositives = this.readEntries(zipEntryData.data());
            entityTypeImportModel.getDeletedFalsePositives().put(zipEntryData.getParentFolder(), falsePositives);
        } else if (zipEntryData.entry().getName().contains(ExportFilename.DELETED_FALSE_RECOMMENDATION.getFilename())) {
            List<String> falseRecommendations = this.readEntries(zipEntryData.data());
            entityTypeImportModel.getDeletedFalseRecommendations().put(zipEntryData.getParentFolder(), falseRecommendations);
        } else {
            return false;
        }
        return true;
    }


    private List<String> readEntries(byte[] bytes) {

        ByteArrayInputStream bInput = new ByteArrayInputStream(bytes);
        try (BufferedReader br = new BufferedReader(new InputStreamReader(bInput, StandardCharsets.UTF_8))) {
            return br.lines()
                    .collect(Collectors.toList());
        } catch (IOException e) {
            log.debug("exception: ", e);
            throw new BadRequestException("Error while reading the entries", e);
        }
    }

}
