package de.ivu.elect.business.dokumente.boundary;

import java.io.ByteArrayOutputStream;
import java.io.InputStream;
import java.io.OutputStream;

import de.ivu.document.generator.template.FileType;
import de.ivu.document.generator.template.OpenOfficeKonfiguration;
import de.ivu.document.generator.template.monitor.DocumentProgressMonitor;
import de.ivu.document.generator.template.openoffice.CheckOOConnection;
import de.ivu.document.generator.template.openoffice.CheckOOConnectionResult;
import de.ivu.document.generator.template.openoffice.OOConnection;
import de.ivu.document.generator.template.pdf.OdtKonvertierer;
import de.ivu.elect.business.dokumente.control.DokumentKonverterLookup;
import de.ivu.elect.business.dokumente.control.OpenOfficeKonfigurationFactory;
import de.ivu.elect.business.dokumente.control.ProgressMonitorWrapper;
import de.ivu.elect.jee.faces.Messages;
import de.ivu.elect.presentation.dokumente.DokumentGenerierenProgressMonitor;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.annotation.Nullable;
import javax.enterprise.inject.Specializes;
import javax.inject.Inject;

@Specializes
public class DokumentVorlageOpenOfficeTestService extends DokumentVorlageOpenOfficeTest {

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

  @Inject
  private transient OpenOfficeKonfigurationFactory openOfficeDokumentKonfiguration;

  @Inject
  private transient DokumentKonverterLookup dokumentKonverterLookup;

  @Inject
  private transient Messages messages;

  @Override
  public DokumentVorlageOpenOfficeTestResult isOpenOfficeAvailable(DokumentGenerierenProgressMonitor monitor) {

    if (!dokumentKonverterLookup.isDokumentKonverterVorhanden()) {
      return fehlerMeldung("open.office.keine.dokumentvorlagen.vorhanden");
    }

    if (!openOfficeDokumentKonfiguration.isOpenOfficeVerfuegbar()) {
      return fehlerMeldung("open.office.nicht.verfuegbar");
    }
    DokumentVorlageOpenOfficeTestResult result = new DokumentVorlageOpenOfficeTestResult();
    CheckOOConnection checkOOConnection = new CheckOOConnection();

    OpenOfficeKonfiguration config = openOfficeDokumentKonfiguration.createConfig();
    LOG.info("Config: " + config);
    ProgressMonitorWrapper monitorDocument = new ProgressMonitorWrapper(monitor);
    CheckOOConnectionResult callResult = checkOOConnection.isConnectionPossible(config, monitorDocument);

    result.setConnectionPossible(callResult.isPossible());
    result.setThrowable(callResult.getThrowable());

    if (result.isConnectionPossible()) {
      LOG.info("Teste Konvertierung");
      try (InputStream sourceInputStream = Thread.currentThread().getContextClassLoader().getResourceAsStream("dummy-test.odt")) {
        try (ByteArrayOutputStream bos = new ByteArrayOutputStream()) {
          new OdtKonvertierer().konvertiereDokument(sourceInputStream, FileType.ODT, null, bos, FileType.PDF, config, monitorDocument);
          result.setConversionPossible(bos.size() > 0);
        }
      } catch (Exception e) {
        result.setConversionPossible(false);
        result.setThrowable(e);
      }
    }
    monitor.getProgressMessages().forEach(result::addMessage);

    LOG.info("result: " + result);
    if (result.getThrowable() != null) {
      LOG.warn("Fehler: " + result.getThrowable().getMessage(), result.getThrowable());
    }

    return result;
  }

  @Override
  public void shutdown(DokumentGenerierenProgressMonitor monitor) {
    try {
      OOConnection.INSTANCE.shutdown(new ProgressMonitorWrapper(monitor));
    } catch (Exception e) {
      monitor.addError("open.office.shutdown.error", e);
    }
  }

  private DokumentVorlageOpenOfficeTestResult fehlerMeldung(String msgKey) {
    DokumentVorlageOpenOfficeTestResult dokumentVorlageOpenOfficeTestResult = new DokumentVorlageOpenOfficeTestResult();
    dokumentVorlageOpenOfficeTestResult.setConnectionPossible(false);
    dokumentVorlageOpenOfficeTestResult.setThrowable(new RuntimeException(messages.getMessageForMessageKey(msgKey)));

    return dokumentVorlageOpenOfficeTestResult;
  }
}
