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

import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

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

import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import de.ivu.elect.business.CurrentCustomer;
import de.ivu.elect.business.version.boundary.AbstractVersion;
import de.ivu.elect.jee.startup.PostStartupAsync;


import static java.util.Arrays.asList;

public class SystemInfoPostStartup implements PostStartupAsync {

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

  private static final List<String> PASSWORD_LIST = asList("password", "passwort", "token", "pwd");

  @Inject
  private transient AbstractVersion version;

  @Inject
  private transient CurrentCustomer currentCustomer;

  @Override
  public void postStartup() {
    try {
      LOG.info("Elect-Info: " + currentCustomer.getCustomer() + ", " + version.getNumber() + ", " + version.getTimestamp());
    } catch (Exception e) {
      LOG.warn("Fehler beim Ausgeben der Versionsnummer");
    }

    // ELECT-9165
    try {
      LOG.info("System-Properties");
      appendVars(new HashMap(System.getProperties()));
      LOG.info("Umgebungsvariablen");
      appendVars(System.getenv());
    } catch (Exception e) {
      LOG.warn("Fehler beim Ausgeben der Umgebunsvariablen");
    }
  }

  private void appendVars(Map<String, ?> m) {
    List<String> keys = new ArrayList<>(m.keySet());
    Collections.sort(keys);
    for (String k : keys) {
      if (isPassword(k)) {
        LOG.info(k + ": ****************");
      } else {
        LOG.info(k + ": " + convertToString(m.get(k)));
      }
    }
  }

  private boolean isPassword(String k) {
    if (StringUtils.isBlank(k)) {
      return false;
    }
    String low = k.toLowerCase();
    return PASSWORD_LIST.stream().anyMatch(low::contains);
  }

  @Nullable
  private String convertToString(Object o) {
    if (o == null) {
      return null;
    }
    return o.toString();
  }

}
