package de.ivu.elect.exchange.csv;

import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.Reader;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;

import com.opencsv.CSVParser;
import com.opencsv.CSVParserBuilder;
import com.opencsv.CSVReader;
import com.opencsv.CSVReaderBuilder;
import com.opencsv.exceptions.CsvValidationException;
import de.ivu.elect.business.datei.entity.CsvAnfuehrungszeichen;
import de.ivu.elect.business.exchange.control.CsvFileKonfiguration;

/**
 * War mal CsvHeaderPrser in dd
 */
public class CsvRawParser {

  public CsvRawParser() {
    super();
  }

  /**
   * Extrahiert die Header-Felder eines als Reader übergebenen CSV-Dokuments gemäß der angegebenen Konfiguration.
   * <p>
   * Der Reader wird nach dem Lesen nicht geschlossen, aber die Leseposition ist nicht unmittelbar nach dem Header.
   */
  public List<String> parseHeader(Reader reader, CsvFileKonfiguration csvFileKonfiguration) throws IOException {

    try (CSVReader csvReader = createReader(reader, csvFileKonfiguration)) {
      String[] strings = csvReader.readNext();
      if (strings == null) {
        return Collections.emptyList();
      }
      return Arrays.asList(strings);
    } catch (CsvValidationException e) {
      throw new RuntimeException(e.getMessage(), e);
    }
  }

  /**
   * Extrahiert die Header-Felder eines als Stream übergebenen CSV-Dokuments gemäß der angegebenen Konfiguration.
   * <p>
   * *** Der Stream wird nach dem Lesen nicht geschlossen, aber die Leseposition ist nicht unmittelbar nach dem Header. ***
   */
  public List<String> parseHeader(InputStream inputStream, CsvFileKonfiguration csvFileKonfiguration) throws IOException {
    return parseHeader(createReader(inputStream, csvFileKonfiguration), csvFileKonfiguration);
  }

  private InputStreamReader createReader(InputStream inputStream, CsvFileKonfiguration csvFileKonfiguration) {
    return new InputStreamReader(inputStream, csvFileKonfiguration.getZeichensatz().toCharset());
  }

  private CSVReader createReader(Reader reader, CsvFileKonfiguration csvFileKonfiguration) {
    boolean ignoreQuotations = CsvAnfuehrungszeichen.OHNE.equals(csvFileKonfiguration.getAnfuehrungszeichen());

    CSVParser csvParser = new CSVParserBuilder()
            .withSeparator(csvFileKonfiguration.getTrennzeichen().getCharacter())
            .withQuoteChar(csvFileKonfiguration.getAnfuehrungszeichen().getCharacter())
            .withStrictQuotes(false)
            .withIgnoreLeadingWhiteSpace(true)
            .withIgnoreQuotations(ignoreQuotations).build();


//    CSVParser csvParser = new CSVParser(csvFileKonfiguration.getTrennzeichen().getCharacter(), csvFileKonfiguration.getAnfuehrungszeichen().getCharacter(),
//        csvFileKonfiguration.getMaskierungszeichen().getCharacter(), false, true, ignoreQuotations);
    //return new CSVReader(reader, 0, csvParser);

    return new CSVReaderBuilder(reader).withCSVParser(csvParser).withSkipLines(0).build();
  }

  public List<List<String>> parseAll(InputStream is, CsvFileKonfiguration csvFileKonfiguration) throws IOException {
    List<List<String>> result = new ArrayList<>();
    try (CSVReader csvReader = createReader(createReader(is, csvFileKonfiguration), csvFileKonfiguration)) {
      String[] strings;
      while ((strings = csvReader.readNext()) != null) {
        result.add(Arrays.asList(strings));
      }
    } catch (CsvValidationException e) {
      throw new RuntimeException(e.getMessage(),e);
    }

    return result;
  }

}
