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

import de.ivu.elect.business.CurrentCustomer;
import de.ivu.elect.business.konfiguration.control.AbstractKonfigurationInit;
import de.ivu.elect.business.konfiguration.entity.ElectKonfigurationWerte;
import de.ivu.elect.business.konfiguration.entity.Konfiguration;
import de.ivu.elect.business.konfiguration.entity.KonfigurationInitContext;
import de.ivu.elect.business.konfiguration.entity.OpenOfficeStartup;
import de.ivu.elect.business.system.boundary.Verzeichnis;
import de.ivu.elect.business.system.entity.VerzeichnisResult;
import org.apache.commons.lang3.StringUtils;

import javax.inject.Inject;
import java.io.File;
import java.util.Collection;

import static java.util.Arrays.asList;
import static java.util.Collections.emptyList;

public class DokumenteKonfigurationInit extends AbstractKonfigurationInit {

  private static final String OPEN_OFFICE_HOME_SYSTEM_PROPERTY_KEY = "de.ivu.elect.open.office.home";

  private static final String OPEN_OFFICE_HOME_DISPLAY_NAME = "OpenOffice Home-Verzeichnis";

  private static final String OPEN_OFFICE_WORK_SYSTEM_PROPERTY_KEY = "de.ivu.elect.open.office.work";

  private static final String OPEN_OFFICE_WORK_DISPLAY_NAME = "LibreOffice Arbeitsverzeichnis";

  @Inject
  private DokumentKonverterLookup dokumentKonverterLookup;

  @Inject
  private transient CurrentCustomer currentCustomer;

  @Inject
  private transient Verzeichnis verzeichnis;

  public DokumenteKonfigurationInit() {
    super();
  }

  @Override
  protected Collection<Konfiguration> createDefaultParameters(KonfigurationInitContext konfigurationInitContext) {
    String officeWorking = tryFindOpenOfficeWorkInSystemProperties();
    // Konfiguration nur anlegen, wenn Dokumentkonverter vorhanden sind
    if (dokumentKonverterLookup.isDokumentKonverterVorhanden()) {
      return asList( //
          create(ElectKonfigurationWerte.OPEN_OFFICE_PATH, tryFindOpenOfficeHomeInSystemProperties()), //
          create(ElectKonfigurationWerte.OPEN_OFFICE_DEFAULT_PORT_NUMBER, getOpenOfficePortNumber()), //
          create(ElectKonfigurationWerte.OPEN_OFFICE_ADDITIONAL_PORT_NUMBERS, ""), //
          create(ElectKonfigurationWerte.OPEN_OFFICE_WORKING_DIR, officeWorking), //
          create(ElectKonfigurationWerte.OPEN_OFFICE_TEMPLATE_PROFILE_DIR, ""), //
          create(ElectKonfigurationWerte.OPEN_OFFICE_KILL_EXISTING_PROCESS, Boolean.TRUE.toString()), //
          create(ElectKonfigurationWerte.OPEN_OFFICE_DISABLE_OPENGL, Boolean.TRUE.toString()), // vermeidet hoffentlich mehr Probleme als es schafft... vielleicht auch für ELECTBB-223
          create(ElectKonfigurationWerte.OPEN_OFFICE_PROCESS_TIMEOUT_IN_MS, getDefaultProcessTimeoutInMs()), //
          create(ElectKonfigurationWerte.OPEN_OFFICE_PROCESS_RETRY_INTERVAL_IN_MS, getDefaultProcessRetryIntervalInMs()), //
          create(ElectKonfigurationWerte.OPEN_OFFICE_TASK_EXECUTION_TIMEOUT_IN_MS, getDefaultTaskExecutionTimeoutInMs()), // zwei Minuten pro Dateikonvertierung
          create(ElectKonfigurationWerte.OPEN_OFFICE_TASK_QUEUE_TIMEOUT_IN_MS, getDefaultTaskQueueTimeoutInMs()),
          create(ElectKonfigurationWerte.OPEN_OFFICE_MAX_TASKS_PER_PROCESS, getMaxTasksPerProcess()),
          create(ElectKonfigurationWerte.OPEN_OFFICE_STARTUP, getStartup()) //
      );
    }

    return emptyList();
  }

  protected int getMaxTasksPerProcess() {
    return 10; // NOTE ELECTBB-223!!!
  }

  protected int getDefaultTaskQueueTimeoutInMs() {
    return 1000 * 60 * 5;  // Fünf Minuten in Warteschlange warten
  }

  protected int getDefaultTaskExecutionTimeoutInMs() {
    return 1000 * 60 * 2; // zwei Minuten pro Dateikonvertierung
  }

  protected int getDefaultProcessRetryIntervalInMs() {
    return 250;
  }

  protected int getDefaultProcessTimeoutInMs() {
    return 30000;
  }

  protected int getOpenOfficePortNumber() {
    return 10000 + currentCustomer.getCustomer().ordinal();
  }

  protected OpenOfficeStartup getStartup() {
    return OpenOfficeStartup.BEI_ERSTEM_ZUGRIFF_STARTEN; // Muss nicht mit Anwendung gestartet werden, startet hinreichend schnell
  }

  private String tryFindOpenOfficeHomeInSystemProperties() {
    String vorgabeVerzeichnis = System.getProperty(OPEN_OFFICE_HOME_SYSTEM_PROPERTY_KEY);

    if (StringUtils.isNotBlank(vorgabeVerzeichnis)) {
      VerzeichnisResult verzeichnisResult = verzeichnis.tryCreateDirectory(OPEN_OFFICE_HOME_DISPLAY_NAME, vorgabeVerzeichnis);
      if (!verzeichnisResult.getVerzeichnisStatus().isFehler()) {
        return verzeichnisResult.getVerzeichnisName();
      }
    }

    return ""; // best guess
  }

  private String tryFindOpenOfficeWorkInSystemProperties() {
    String vorgabeVerzeichnis = System.getProperty(OPEN_OFFICE_WORK_SYSTEM_PROPERTY_KEY);

    if (StringUtils.isNotBlank(vorgabeVerzeichnis)) {
      VerzeichnisResult verzeichnisResult = verzeichnis.tryCreateDirectory(OPEN_OFFICE_WORK_DISPLAY_NAME, vorgabeVerzeichnis);
      if (!verzeichnisResult.getVerzeichnisStatus().isFehler()) {
        return verzeichnisResult.getVerzeichnisName();
      }
    }

    return tryCreateUserHomeDirectory(OPEN_OFFICE_WORK_DISPLAY_NAME, "office" + File.separator + "working").getVerzeichnisName();
  }
}
