
package de.ivu.elect.business;

import static java.util.Arrays.asList;
import static org.apache.commons.lang3.StringUtils.isNotBlank;
import static org.apache.commons.lang3.StringUtils.leftPad;

import java.util.List;

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

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

import de.ivu.elect.business.gebietsbaum.boundary.GebietsartCreator;
import de.ivu.elect.business.konfiguration.control.KonfigurationCreator;
import de.ivu.elect.business.lokalisierung.control.LokalisierungInit;
import de.ivu.elect.business.mandant.control.MandantInit;
import de.ivu.elect.business.mandant.control.MandantSupportErmittler;
import de.ivu.elect.business.security.boundary.BenutzerCreator;
import de.ivu.elect.business.security.boundary.RolleCreator;
import de.ivu.elect.business.staat.boundary.StaatCreator;
import de.ivu.elect.business.system.control.SystemStatusInit;
import de.ivu.elect.business.wahl.boundary.WahlartCreator;
import de.ivu.elect.jee.jboss.JBossVersion;
import de.ivu.elect.jee.startup.StartupBootstrap;

@Specializes
public class BaseStartup extends StartupBootstrap {

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

  private static final List<String> SYS_ENVS = asList( //
      "COMPUTERNAME", //
      "OS", //
      "SESSIONNAME", //
      "NUMBER_OF_PROCESSORS", //
      "PROCESSOR_IDENTIFIER", //
      "PROCESSOR_ARCHITECTURE", //
      "PROCESSOR_ARCHITEW6432", //
      "PROCESSOR_LEVEL", //
      "PROCESSOR_REVISION" //
  );

  @Inject
  private transient JBossVersion jBossVersion;

  @Inject
  private transient CurrentCustomer currentCustomer;

  @Inject
  private transient KonfigurationCreator konfigurationCreator;

  @Inject
  private transient RolleCreator rolleCreator;

  @Inject
  private transient BenutzerCreator benutzerCreator;

  @Inject
  private transient WahlartCreator wahlartCreator;

  @Inject
  private transient GebietsartCreator gebietsartCreator;

  @Inject
  private transient StaatCreator staatCreator;

  @Inject
  private transient LokalisierungInit lokalisierungInit;

  @Inject
  private transient SystemStatusInit systemStatusInit;

  @Inject
  private transient MandantSupportErmittler mandantSupportErmittler;

  @Inject
  private transient MandantInit mandantInit;

  public BaseStartup() {
    super();
  }

  protected String getAppName() {
    return "elect iT " + currentCustomer.getCustomer().getBezeichnung();
  }

  @Override
  protected void init() {
    super.init();
    LOG.info(getAppName() + " - starting");

    dumpElectLogo();
    dumpSystemInfo();
    dumpAppServerVersion();

    lokalisierungInit.init();

    mandantSupportErmittler.init();

    if (isStammdatenInitialisieren()) {
      LOG.info(getAppName() + " - System-Mandant anlegen");
      mandantInit.initialisiereSystemMandant();
      mandantInit.initialisiereKundenMandant();
      LOG.info(getAppName() + " - System-Mandant angelegt");
    }

    if (isStammdatenInitialisieren()) {
      LOG.info(getAppName() + " - Konfigurationsparameter anlegen");
      konfigurationCreator.initKonfigurationAlleMandanten();
      LOG.info(getAppName() + " - Konfigurationsparameter angelegt");
    }

    if (isStammdatenInitialisieren()) {
      LOG.info(getAppName() + " - Rollen anlegen");
      rolleCreator.initRollenAlleMandanten();
      LOG.info(getAppName() + " - Rollen angelegt");
    }

    if (isStammdatenInitialisieren()) {
      LOG.info(getAppName() + " - Produktiv- / Testrechte initial anlegen");
      rolleCreator.initProduktivTestRechteAlleMandanten();
      rolleCreator.cleanUpProduktivTestRechteAlleMandanten(); // WASDE-1089
      LOG.info(getAppName() + " - Produktiv- / Testrechte initial angelegt");
    }

    if (isStammdatenInitialisieren()) {
      rolleCreator.aktualisiereAdminRolleAlleMandanten();
      rolleCreator.cleanUpRollenAlleMandanten(); // WASDE-1089
    }

    if (isStammdatenInitialisieren()) {
      LOG.info(getAppName() + " - Benutzer anlegen");
      benutzerCreator.initBenutzerAlleMandanten();
      LOG.info(getAppName() + " - Benutzer angelegt");
    }

    if (isStammdatenInitialisieren()) {
      LOG.info(getAppName() + " - Gebietsarten anlegen");
      initGebietsarten();
      LOG.info(getAppName() + " - Gebietsarten angelegt");
    }

    if (isStammdatenInitialisieren()) {
      initWahlarten();
    }

    if (isStammdatenInitialisieren()) {
      LOG.info(getAppName() + " - Systemstatus setzen");
      systemStatusInit.initAlleMandanten();
      LOG.info(getAppName() + " - Systemstatus gesetzt");
    }

    if (isStammdatenInitialisieren()) {
      LOG.info(getAppName() + " - Staaten anlegen");
      staatCreator.initStaaten();
      LOG.info(getAppName() + " - Staaten angelegt");
    }

    LOG.info(getAppName() + " - started");
  }

  protected void initWahlarten() {
    LOG.info(getAppName() + " - Wahlarten anlegen");
    wahlartCreator.initWahlartenAlleMandanten();
    LOG.info(getAppName() + " - Wahlarten angelegt");
  }

  // Cf. http://www.network-science.de/ascii/ascii.php?TEXT=elect&x=13&y=16&FONT=cyberlarge&RICH=no&FORM=left&STRE=no&WIDT=70
  private void dumpElectLogo() {
    String tab = calculateLogoTab(LOG);

    LOG.info(tab + "_______        _______ _______ _______");
    LOG.info(tab + "|______ |      |______ |          |  ");
    LOG.info(tab + "|______ |_____ |______ |_____     |  ");
    LOG.info(tab + "                                     ");
  }

  private void dumpSystemInfo() {
    String tab = calculateLogoTab(LOG);

    LOG.info(tab + "System-Info ");

    for (String s : SYS_ENVS) {
      String value = System.getenv(s);

      if (isNotBlank(value)) {
        LOG.info(tab + s + ": " + value);
      }
    }
  }

  private void dumpAppServerVersion() {
    String tab = calculateLogoTab(LOG);

    LOG.info(tab + "WildFly version: " + jBossVersion.getServerVersion());
  }

  protected void initGebietsarten() {
    gebietsartCreator.initGebietsartenAlleMandanten();
  }

  /**
   * WASDE-597
   */
  public boolean isStammdatenInitialisieren() {
    return true;
  }

  protected static String calculateLogoTab(Logger log) {
    int startupImplLoggerNameMaxLength = "de.ivu.elect.business.DestatisWusExternStartup".length() + 1;

    return leftPad("", Math.max(1, startupImplLoggerNameMaxLength - log.getName().length()), " ");
  }
}
