
package de.ivu.elect.business.datei.control;

import static java.util.stream.Collectors.toList;

import java.io.IOException;
import java.nio.charset.Charset;
import java.util.List;

import javax.inject.Inject;

import de.ivu.elect.business.datei.entity.CsvDatei;
import de.ivu.elect.business.exchange.control.ImportExportStreamCreator;
import de.ivu.elect.business.konfiguration.control.StreamCreator;

public class CsvDateiLeser extends AbstractDateiLeser {

  private static final long serialVersionUID = 1L;

  private static final int MAX_BYTES_EXPECTED_PER_LINE = 5000;

  @Inject
  private transient ImportExportStreamCreator streamCreator;

  @Inject
  private transient CsvDateiLeserMapper csvDateiLeserMapper;

  public CsvDateiLeser() {
    super();
  }

  public List<String[]> liesDatenAlsCsvDatei(CsvDatei csvDatei, int maxLinesCount) throws IOException {
    return liesDatenAlsCsvDatei(streamCreator, csvDatei, maxLinesCount);
  }

  public List<String[]> liesDatenAlsCsvDatei(StreamCreator streamCreator, CsvDatei csvDatei, int maxLinesCount) throws IOException {
    return mapLineToCsvValuesColumnCountNormalized(csvDatei, readMaxLines(streamCreator, csvDatei, maxLinesCount));
  }

  private List<String[]> mapLineToCsvValuesColumnCountNormalized(CsvDatei csvDatei, List<String> lines) throws IOException {
    try {
      return csvDateiLeserMapper.mapColumnCountNormalized(csvDatei, lines);
    } catch (Exception ex) {
      throw new IOException("Fehler beim Einlesen der CSV-Datei", ex);
    }
  }

  public List<String[]> liesDatenAlsZeilen(CsvDatei csvDatei, int maxLinesCount) throws IOException {
    return liesDatenAlsZeilen(streamCreator, csvDatei, maxLinesCount);
  }

  public List<String[]> liesDatenAlsZeilen(StreamCreator streamCreator, CsvDatei csvDatei, int maxLinesCount) throws IOException {
    return mapLineToSingleValue(csvDatei, readMaxLines(streamCreator, csvDatei, maxLinesCount));
  }

  private List<String[]> mapLineToSingleValue(CsvDatei csvDatei, List<String> lines) {
    return lines.stream() //
        .map(line -> new String[] {line}) //
        .collect(toList());
  }

  private List<String> readMaxLines(StreamCreator streamCreator, CsvDatei csvDatei, int maxLinesCount) throws IOException {
    Charset charset = csvDatei.getZeichensatz().toCharset();
    int maxBytesCount = maxLinesCount * MAX_BYTES_EXPECTED_PER_LINE;

    return readLines(streamCreator, csvDatei, charset, maxBytesCount, maxLinesCount);
  }
}
