package no.valg.valgnatt.database.forberedvalg;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.Reader;
import java.nio.file.Files;
import java.util.Map;
import java.util.SortedMap;
import java.util.TreeMap;

import no.valg.valgnatt.database.forberedvalg.bean.Bean;
import no.valg.valgnatt.database.forberedvalg.csv.Csv;

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.supercsv.cellprocessor.ift.CellProcessor;
import org.supercsv.io.CsvBeanReader;
import org.supercsv.io.CsvBeanWriter;
import org.supercsv.io.ICsvBeanReader;
import org.supercsv.io.ICsvBeanWriter;

public class LoadSave {

    private static final Logger LOG = LogManager.getLogger(LoadSave.class);

    private LoadSave() {
        //Hide default constructor
    }

    public static <T extends Bean> SortedMap<String, T> load(String dirName, Csv csv, Class<T> clazz) throws IOException {
        String fullName = dirName + csv.getFileName();
        LOG.info("Leser " + fullName);

        Reader reader;
        InputStream resourceAsStream = LoadSave.class.getClassLoader().getResourceAsStream(fullName);
        if (resourceAsStream != null) {
            reader = new InputStreamReader(resourceAsStream);
        } else {
            reader = new BufferedReader(new FileReader(fullName));
        }

        ICsvBeanReader beanReader = new CsvBeanReader(reader, csv.getPreference());

        csv.readHeader(beanReader);
        SortedMap<String, T> map = new TreeMap<>();
        T current;
        String[] header = csv.getHeader();
        CellProcessor[] processors = csv.getProcessors();
        while ((current = beanReader.read(clazz, header, processors)) != null) {
            map.put(current.getKey(), current);
        }
        beanReader.close();
        reader.close();
        return map;
    }

    public static <T extends Bean> void save(String dirName, Csv csv, Map<String, T> map) throws IOException {
        Files.createDirectories(new File(dirName).toPath());
        String fullName = dirName + csv.getFileName();
        LOG.info("Skriver " + fullName);
        try (FileWriter fileWriter = new FileWriter(fullName)) {
            ICsvBeanWriter beanWriter = new CsvBeanWriter(new BufferedWriter(fileWriter), csv.getPreference());
            String[] header = csv.getHeader();
            CellProcessor[] processors = csv.getProcessors();
            beanWriter.writeHeader(header);
            for (T current : map.values()) {
                beanWriter.write(current, header, processors);
            }
            beanWriter.close();
        }
    }

}
