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

import java.io.IOException;
import java.io.InputStream;
import java.io.Serializable;
import java.util.Collections;
import java.util.List;
import java.util.Objects;
import java.util.zip.ZipInputStream;

import javax.inject.Inject;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import de.ivu.elect.business.datei.entity.Datei;
import de.ivu.elect.business.internet.entity.PraesentationUploadServiceParameter;
import de.ivu.elect.business.praesentation.entity.PraesentationUploadServiceStatus;
import de.ivu.elect.business.praesentation.entity.PraesentationUploadServiceTyp;
import de.ivu.elect.business.wahl.entity.Wahl;
import de.ivu.elect.business.wahl.entity.WahlParameter;
import de.ivu.elect.business.wahl.entity.WahlParameterLoader;
import de.ivu.elect.business.wahl.entity.WahlParameterWerte;
import de.ivu.elect.business.wahl.entity.Wahldurchfuehrung;
import de.ivu.elect.jee.faces.Messages;

public class PraesentationUploadServiceControl implements Serializable {
  private static final Logger LOG = LoggerFactory.getLogger(PraesentationUploadServiceControl.class);

  private static final long serialVersionUID = 1L;

  @Inject
  private transient PraesentationUploadServiceFinder praesentationUploadServiceFinder;

  @Inject
  private transient Messages messages;

  @Inject
  private transient WahlParameterLoader wahlParameterLoader;

  public PraesentationUploadServiceTyp getPraesentationUploadServiceTyp(Wahldurchfuehrung wahldurchfuehrung) {
    return wahlParameterLoader.resolveEnumValue(wahldurchfuehrung, WahlParameterWerte.PREASENTATIION_UPLOAD_SERVICE_TYP, PraesentationUploadServiceTyp.class);
  }

  public PraesentationUploadServiceStatus getPraesentationUploadServiceStatus(Wahl wahldurchfuehrung) {
    return wahlParameterLoader
      .resolveEnumValue(wahldurchfuehrung, WahlParameterWerte.PREASENTATIION_UPLOAD_SERVICE_STATUS, PraesentationUploadServiceStatus.class);
  }

  public List<String> isUploadServiceAvailable(Wahldurchfuehrung wahldurchfuehrung) {
    try {
      PraesentationUploadService praesentationUploadService = praesentationUploadServiceFinder
          .getPraesentationUploadService(getPraesentationUploadServiceTyp(wahldurchfuehrung));
      PraesentationUploadServiceParameter praesentationUploadServiceParameter =
          getPraesentationUploadServiceParameter(wahldurchfuehrung);

      String configBeforeConnection = praesentationUploadServiceParameter
          .getKonfiguration();

      List<String> isConnectionPossible = praesentationUploadService
          .isConnectionPossible(praesentationUploadServiceParameter);

      String configAfterConnection = praesentationUploadServiceParameter
          .getParsedKonfigJson();

      if (configAfterConnection != null &&
          !Objects.equals(configBeforeConnection, configAfterConnection)) {
        updatePraesentationUploadServiceConfig(wahldurchfuehrung,
            praesentationUploadServiceParameter);
      }

      return isConnectionPossible;
    } catch (Exception e) {
      LOG.warn("Fehler bei PraesentationUploadService: " + e.getMessage());
      return Collections.singletonList(messages.getMessageForMessageKey("praesentation.upload.service.fehler", e.getMessage()));
    }
  }

  public void uploadFileIfPossible(Wahldurchfuehrung wahldurchfuehrung, InputStream inputStream, Datei datei) throws IOException {

    PraesentationUploadService praesentationUploadService = praesentationUploadServiceFinder.getPraesentationUploadService(getPraesentationUploadServiceTyp(wahldurchfuehrung));
    PraesentationUploadServiceParameter praesentationUploadServiceParameter = getPraesentationUploadServiceParameter(wahldurchfuehrung);
    try (ZipInputStream zis = new ZipInputStream(inputStream) {
      @Override
      public void close() throws IOException {
        // ignore
      }
    }) {
      LOG.info("Starte Upload");
      praesentationUploadService.uploadFiles(praesentationUploadServiceParameter, zis, datei);
      LOG.info("Upload - done");
    }
  }

  private PraesentationUploadServiceParameter getPraesentationUploadServiceParameter(Wahldurchfuehrung wahldurchfuehrung) {
    PraesentationUploadServiceTyp serviceTyp = wahlParameterLoader
      .resolveEnumValue(wahldurchfuehrung, WahlParameterWerte.PREASENTATIION_UPLOAD_SERVICE_TYP, PraesentationUploadServiceTyp.class);
    String url = wahlParameterLoader.resolveStringValue(wahldurchfuehrung, WahlParameterWerte.PREASENTATIION_UPLOAD_SERVICE_URL);
    String benutzer = wahlParameterLoader.resolveStringValue(wahldurchfuehrung, WahlParameterWerte.PREASENTATIION_UPLOAD_SERVICE_BENUTZER);
    String passwort = wahlParameterLoader.resolveStringValue(wahldurchfuehrung, WahlParameterWerte.PREASENTATIION_UPLOAD_SERVICE_PASSWORT);
    String konfig = wahlParameterLoader.resolveStringValue(wahldurchfuehrung, WahlParameterWerte.PREASENTATIION_UPLOAD_SERVICE_KONFIG);
    return new PraesentationUploadServiceParameter(serviceTyp, url, benutzer, passwort, konfig);
  }

  public boolean isUploadAktiviert(Wahl wahldurchfuehrung) {
    return getPraesentationUploadServiceStatus(wahldurchfuehrung).isAktiv();
  }

  public void disableUploadServiceError(Wahl wahl) {
    WahlParameter parameter = wahlParameterLoader.getParameter(wahl, WahlParameterWerte.PREASENTATIION_UPLOAD_SERVICE_STATUS);
    if (parameter != null) {
      parameter.setWert(PraesentationUploadServiceStatus.FEHLERHAFT.name());
    }
  }

  private void updatePraesentationUploadServiceConfig(Wahldurchfuehrung wahldurchfuehrung,
      PraesentationUploadServiceParameter praesentationUploadServiceParameter) {
    WahlParameter konfiguration = wahlParameterLoader.getParameter(wahldurchfuehrung,
        WahlParameterWerte.PREASENTATIION_UPLOAD_SERVICE_KONFIG);
    konfiguration.setWert(praesentationUploadServiceParameter.getParsedKonfigJson());
  }
}
