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

import java.util.Arrays;
import java.util.Objects;

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

import org.apache.commons.lang3.ArrayUtils;
import org.apache.commons.lang3.StringUtils;

import de.ivu.document.generator.template.OpenOfficeKonfiguration;
import de.ivu.elect.business.konfiguration.entity.KonfigurationLoader;


import static de.ivu.elect.business.konfiguration.entity.ElectKonfigurationWerte.OPEN_OFFICE_ADDITIONAL_PORT_NUMBERS;
import static de.ivu.elect.business.konfiguration.entity.ElectKonfigurationWerte.OPEN_OFFICE_DEFAULT_PORT_NUMBER;
import static de.ivu.elect.business.konfiguration.entity.ElectKonfigurationWerte.OPEN_OFFICE_DISABLE_OPENGL;
import static de.ivu.elect.business.konfiguration.entity.ElectKonfigurationWerte.OPEN_OFFICE_FAIL_FAST;
import static de.ivu.elect.business.konfiguration.entity.ElectKonfigurationWerte.OPEN_OFFICE_KILL_EXISTING_PROCESS;
import static de.ivu.elect.business.konfiguration.entity.ElectKonfigurationWerte.OPEN_OFFICE_MAX_RETRIES_CANCELLATION;
import static de.ivu.elect.business.konfiguration.entity.ElectKonfigurationWerte.OPEN_OFFICE_MAX_TASKS_PER_PROCESS;
import static de.ivu.elect.business.konfiguration.entity.ElectKonfigurationWerte.OPEN_OFFICE_PATH;
import static de.ivu.elect.business.konfiguration.entity.ElectKonfigurationWerte.OPEN_OFFICE_PROCESS_RETRY_INTERVAL_IN_MS;
import static de.ivu.elect.business.konfiguration.entity.ElectKonfigurationWerte.OPEN_OFFICE_PROCESS_TIMEOUT_IN_MS;
import static de.ivu.elect.business.konfiguration.entity.ElectKonfigurationWerte.OPEN_OFFICE_TASK_EXECUTION_TIMEOUT_IN_MS;
import static de.ivu.elect.business.konfiguration.entity.ElectKonfigurationWerte.OPEN_OFFICE_TASK_QUEUE_TIMEOUT_IN_MS;
import static de.ivu.elect.business.konfiguration.entity.ElectKonfigurationWerte.OPEN_OFFICE_TEMPLATE_PROFILE_DIR;
import static de.ivu.elect.business.konfiguration.entity.ElectKonfigurationWerte.OPEN_OFFICE_WORKING_DIR;

/**
 *  on 11.11.2016.
 */
@Stateless
@Specializes
public class OpenOfficeKonfigurationFactory extends BaseOpenOfficeKonfigurationFactory {

  private static final long serialVersionUID = 1L;

  @Inject
  private transient OpenOfficeApplication openOfficeApplication;

  @Inject
  private transient KonfigurationLoader konfigurationLoader;

  public OpenOfficeKonfiguration createConfig() {
    openOfficeApplication.foo();
    String openOfficePath = emptyToNull(konfigurationLoader.resolveStringValue(OPEN_OFFICE_PATH));
    int[] portNumbers = bestimmePortnummern();
    String workingDir = emptyToNull(konfigurationLoader.resolveStringValue(OPEN_OFFICE_WORKING_DIR));
    boolean killExistingProcess = konfigurationLoader.resolveBooleanValue(OPEN_OFFICE_KILL_EXISTING_PROCESS);
    boolean disableOpengl = konfigurationLoader.resolveBooleanValue(OPEN_OFFICE_DISABLE_OPENGL);
    boolean failFast = konfigurationLoader.resolveBooleanValue(OPEN_OFFICE_FAIL_FAST);
    long processTimeoutInMs = konfigurationLoader.resolveLongValue(OPEN_OFFICE_PROCESS_TIMEOUT_IN_MS);
    long processRetryIntervalnMs = konfigurationLoader.resolveLongValue(OPEN_OFFICE_PROCESS_RETRY_INTERVAL_IN_MS);
    long taskExecutionTimeoutInMs = konfigurationLoader.resolveLongValue(OPEN_OFFICE_TASK_EXECUTION_TIMEOUT_IN_MS);
    long taskQueueTimeoutInMs = konfigurationLoader.resolveLongValue(OPEN_OFFICE_TASK_QUEUE_TIMEOUT_IN_MS);
    int maxTasksPerProcess = konfigurationLoader.resolveIntegerValue(OPEN_OFFICE_MAX_TASKS_PER_PROCESS);
    int maxRetriesCancellation = konfigurationLoader.resolveIntegerValue(OPEN_OFFICE_MAX_RETRIES_CANCELLATION);
    String templateProfileDir = emptyToNull(konfigurationLoader.resolveStringValue(OPEN_OFFICE_TEMPLATE_PROFILE_DIR));

    OpenOfficeKonfiguration openOfficeKonfiguration = new OpenOfficeKonfiguration() {
      @Nullable
      @Override
      public String getOpenOfficePath() {
        return openOfficePath;
      }

      @Override
      public int[] getOpenOfficePortNumbers() {
        return portNumbers;
      }

      @Nullable
      @Override
      public String getWorkingDir() {
        return workingDir;
      }

      @Override
      public boolean killExistingProcess() {
        return killExistingProcess;
      }

      @Override
      public boolean disableOpengl() {
        return disableOpengl;
      }

      @Override
      public long getProcessTimeoutInMs() {
        return processTimeoutInMs;
      }

      @Override
      public long getProcessRetryIntervalnMs() {
        return processRetryIntervalnMs;
      }

      @Override
      public long getTaskExecutionTimeoutInMs() {
        return taskExecutionTimeoutInMs;
      }

      @Override
      public int getMaxTasksPerProcess() {
        return maxTasksPerProcess;
      }

      @Nullable
      @Override
      public String getTemplateProfileDir() {
        return templateProfileDir;
      }

      @Override
      public long getTaskQueueTimeoutInMs() {
        return taskQueueTimeoutInMs;
      }

      @Override
      public long getAnzahlRetries() {
        return maxRetriesCancellation;
      }

      @Override
      public boolean isFailFast() {
        return failFast;
      }

      @Override
      public String toString() {
        return "OpenOfficeKonfiguration{" +
            "openOfficePath='" + getOpenOfficePath() + '\'' +
            ", openOfficePortNumbers=" + Arrays.toString(getOpenOfficePortNumbers()) +
            ", workingDir='" + getWorkingDir() + '\'' +
            ", killExistingProcess=" + killExistingProcess() +
            ", disableOpengl=" + disableOpengl() +
            ", processTimeoutInMs=" + getProcessTimeoutInMs() +
            ", processRetryIntervalnMs=" + getProcessRetryIntervalnMs() +
            ", taskExecutionTimeoutInMs=" + getTaskExecutionTimeoutInMs() +
            ", maxTasksPerProcess=" + getMaxTasksPerProcess() +
            ", templateProfileDir='" + getTemplateProfileDir() + '\'' +
            ", taskQueueTimeoutInMs=" + getTaskQueueTimeoutInMs() +
            ", anzahlRetries=" + getAnzahlRetries() +
            '}';
      }
    };
    // System.out.println("openOfficeKonfiguration = " + openOfficeKonfiguration);
    return openOfficeKonfiguration;
  }

  private String emptyToNull(String s) {
    if (StringUtils.isBlank(s)) {
      return null;
    }
    return s;
  }

  private int[] bestimmePortnummern() {

    int portNumber = konfigurationLoader.resolveIntegerValue(OPEN_OFFICE_DEFAULT_PORT_NUMBER);

    String additonal = konfigurationLoader.resolveStringValue(OPEN_OFFICE_ADDITIONAL_PORT_NUMBERS);

    if (StringUtils.isNotBlank(additonal)) {
      int[] additionalPorts = Arrays.stream(additonal.split(",")).filter(Objects::nonNull).map(String::trim).mapToInt(Integer::parseInt).toArray();
      return ArrayUtils.add(additionalPorts, portNumber);
    }

    return new int[]{portNumber};
  }

}
