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

import java.io.File;
import java.io.InputStream;
import java.io.OutputStream;

import javax.annotation.Nullable;

import org.primefaces.model.DefaultStreamedContent;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import de.ivu.elect.business.exchange.control.FileFormat;
import de.ivu.elect.business.konfiguration.control.StreamCreator;
import de.ivu.elect.business.konfiguration.entity.InputStreamMitGroesse;
import de.ivu.elect.business.mandant.entity.EntityMitMandant;
import de.ivu.elect.business.mandant.entity.Mandant;
import de.ivu.elect.business.wahl.entity.Wahl;

public abstract class AbstractDatei implements DateiBase, EntityMitMandant {

  private static final Logger LOG = LoggerFactory.getLogger(AbstractDatei.class);

  private static final long serialVersionUID = 1L;

  /**
   * Verwendet in Zusammenhang mit ????
   */
  // TODO ELECT-5274
  private transient byte[] nichtPersistenterInhalt;

  public byte[] getNichtPersistenterInhalt() {
    return nichtPersistenterInhalt;
  }

  public void setNichtPersistenterInhalt(byte[] dateiInhalt) {
    this.nichtPersistenterInhalt = dateiInhalt;
  }

  public boolean isCsvDatei() {
    return FileType.CSV.equals(getFileType());
  }

  public boolean isXmlDatei() {
    return FileType.XML.equals(getFileType());
  }

  public boolean isZipDatei() {
    return FileType.ZIP.equals(getFileType());
  }

  public boolean isOdtDatei() {
    return FileType.ODT.equals(getFileType());
  }

  public InputStream createInputStream(StreamCreator streamCreator) {
    return streamCreator.createInputStreamForDatei(getDateiname(), getPfad()).getInputStream();
  }

  public OutputStream createOutputStream(StreamCreator streamCreator) {
    return streamCreator.createOutputStreamForDatei(getDateiname(), getPfad());
  }

  public File createFile(StreamCreator streamCreator) {
    return streamCreator.createFile(getDateiname(), getPfad());
  }

  public DefaultStreamedContent getDefaultStreamedContent(StreamCreator streamCreator) {
    return getDefaultStreamedContent(streamCreator, null);
  }

  public DefaultStreamedContent getDefaultStreamedContent(StreamCreator streamCreator, @Nullable DateiDownloadEvent event) {
    InputStreamMitGroesse inputStreamForDatei = streamCreator.createInputStreamForDatei(getDateiname(), getPfad());

    if (event != null) {
      inputStreamForDatei.setStreamCloseListener(() -> {
        try {
          event.fire(getPk());
        } catch (Exception e) {
          // ignore
          LOG.warn("Download event: " + e.getMessage() + ", " + getPk());
        }
      });
    }
    return DefaultStreamedContent.builder()
        .stream(() -> inputStreamForDatei.getInputStream())
        .contentType(getMimeType())
        .name(getOriginalDateiname())
        .contentLength(inputStreamForDatei.getSize())
        .build();
  }

  public boolean isFileFormat(FileFormat other) {
    return getFileFormat().equals(other);
  }

  public FileFormat getFileFormat() {
    return new FileFormat(getFormat(), getFileType());
  }

  public void setFileFormat(FileFormat fileFormat) {
    setFormat(fileFormat.getName());
    setFileType(fileFormat.getFileType());
  }

  protected void postSetWahl(Wahl alterWert, Wahl neuerWert) {
    // nichts zu tun
  }

  protected void preSetWahl(Wahl alterWert, Wahl neuerWert) {
    if (neuerWert == null) {
      setWahltermin(null);
    } else {
      setWahltermin(neuerWert.getWahltermin());
    }
  }

  public String getNameWahlOrWahltermin() {

    if (getWahl() == null) {
      if (getWahltermin() == null) {
        return null;
      }
      return getWahltermin().getName();
    }
    return getWahl().getName();
  }

  @Override
  @Nullable
  public EntityMitMandant getParent() {
    return null;
  }

  @Override
  public abstract Mandant getMandant();
}
