package de.ivu.elect.presentation.security;

import java.io.Serializable;

import javax.annotation.Nullable;
import javax.enterprise.context.RequestScoped;
import javax.inject.Inject;
import javax.inject.Named;
import javax.servlet.http.HttpSession;

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

import de.ivu.elect.business.benutzerverwaltung.entity.Benutzer;
import de.ivu.elect.business.benutzerverwaltung.entity.BenutzerPK;
import de.ivu.elect.business.security.control.ElectCommonPrincipal;
import de.ivu.elect.business.security.control.NlAirGapStatusEvent;
import de.ivu.elect.jee.faces.FacesContextUtil;
import de.ivu.elect.jee.security.IpHostname;
import de.ivu.elect.jee.security.LoginIpBestimmer;
import de.ivu.elect.jee.session.SessionIdFilter;

@Named(NlAirGapListener.COMPONENT_NAME)
@RequestScoped
public class NlAirGapListener implements Serializable {
  private static final long serialVersionUID = 1L;

  public static final String COMPONENT_NAME = "nlAirGapListener";

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

  @Inject
  private transient LoginIpBestimmer loginIpBestimmer;

  @Inject
  private transient ElectCommonPrincipal principal;

  @Inject
  private transient NlAirGapStatusEvent nlAirGapStatusEvent;

  public void airGapDetected() {
    IpHostname ipHostname = bestimmeIpHostname();
    Benutzer benutzer = bestimmeBenutzer();
    String sessionId = getSessionId();
    LOG.warn("Client side airgap detected - ip: " + ipHostname + ", user: " + benutzer + ", SessionId: " + SessionIdFilter.maskiere(sessionId));
    nlAirGapStatusEvent.sendClientAirGapEvent(ipHostname, getBenutzerPk(benutzer), sessionId);
  }

  @Nullable
  private BenutzerPK getBenutzerPk(Benutzer benutzer) {
    if (benutzer == null) {
      return null;
    }
    return benutzer.getPk();
  }

  @Nullable
  private String getSessionId() {
    try {
      HttpSession session = (HttpSession) FacesContextUtil.getExternalContext().getSession(false);
      if (session != null) {
        return session.getId();
      }
    } catch (Exception e) {
      LOG.warn("Error sessionId: " + e.getMessage());
    }

    return null;
  }

  @Nullable
  private Benutzer bestimmeBenutzer() {
    try {
      if (principal.isLoggedIn()) {
        return principal.getLogin();
      }
    } catch (Exception e) {
      LOG.warn("Error user: " + e.getMessage());
    }

    return null;
  }

  private IpHostname bestimmeIpHostname() {
    try {
      if (principal.isLoggedIn()) {
        IpHostname ipHostname = principal.getIpHostname();
        if (!IpHostname.UNBEKANNT.equals(ipHostname)) {
          return ipHostname;
        }
      }
      return loginIpBestimmer.bestimmeIpAdresseAusRequest();
    } catch (Exception e) {
      LOG.warn("Error Ip: " + e.getMessage());
      return IpHostname.UNBEKANNT;
    }

  }

}
