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

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.Serializable;
import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.List;
import java.util.zip.ZipInputStream;

import de.ivu.elect.business.datei.entity.Datei;
import de.ivu.elect.business.konfiguration.control.StreamCreator;
import de.ivu.elect.util.LimitedInputStream;

public abstract class AbstractDateiLeser implements Serializable {

  private static final long serialVersionUID = 1L;

  public AbstractDateiLeser() {
    super();
  }

  protected List<String> readLines(StreamCreator streamCreator, Datei datei, Charset charset, int maxBytesCount, int maxLinesCount)
      throws IOException {
    try (BufferedReader bufferedReader = createLimitedBufferedReader(streamCreator, datei, charset, maxBytesCount)) {
      return readLines(bufferedReader, maxLinesCount);
    } catch (Exception ex) {
      throw new IOException("Fehler beim Lesen der ersten " + maxLinesCount + " Zeilen von " + maxBytesCount + " Bytes", ex);
    }
  }

  protected List<String> readLines(BufferedReader bufferedReader, int maxLinesCount) throws IOException {
    List<String> result = new ArrayList<>();

    for (int i = 0; i < maxLinesCount; i++) {
      String nextLine = bufferedReader.readLine();

      if (nextLine == null) {
        break;
      }

      result.add(nextLine);
    }

    return result;
  }

  protected BufferedReader createLimitedBufferedReader(StreamCreator streamCreator, Datei datei, Charset charset, int maxBytesCount)
      throws Exception {
    return new BufferedReader(
        new InputStreamReader(new LimitedInputStream(createInputStream(streamCreator, datei), maxBytesCount), charset));
  }

  protected ZipInputStream createZipInputStream(StreamCreator streamCreator, Datei datei) {
    return new ZipInputStream(createInputStream(streamCreator, datei));
  }

  protected InputStream createInputStream(StreamCreator streamCreator, Datei datei) {
    return datei.createInputStream(streamCreator);
  }
}
