package de.ivu.elect.business.benutzerverwaltung.entity;

import java.io.Serializable;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.concurrent.atomic.AtomicLong;

import org.apache.commons.lang3.StringUtils;

import de.ivu.elect.jee.entity.Entity;
import de.ivu.elect.jee.entity.EntityContainer;
import de.ivu.elect.jee.entity.EntityFachlichAbhaengigNode;
import de.ivu.elect.jee.entity.EntityLongPK;
import de.ivu.elect.jee.entity.tk.EntityTK;
import de.ivu.elect.jee.entity.tk.EntityUK;
import de.ivu.elect.jee.protokollierung.AttributWertVorher;
import de.ivu.elect.jee.protokollierung.VorherNachherWert;
import de.ivu.elect.jee.security.IpHostname;

public class AngemeldeterBenutzer
    implements
    Entity<EntityLongPK, EntityUK>,
    Serializable,
    Comparable<AngemeldeterBenutzer> {

  private static final long serialVersionUID = 1L;

  private final Long id;

  private final Long mandantNummer;

  private final String benutzerkennung;

  private final String sessionId;

  private final IpHostname ipAdresse;

  private final Date anmeldezeit;

  private final List<String> rollen;

  private final AtomicLong letzteInteraktion = new AtomicLong(0L);

  private final String benutzerEinsatzort;

  private final BenutzerPK benutzerPK;

  public AngemeldeterBenutzer(Long id, String sessionId, BenutzerPK benutzerPK, Long mandantNummer, String benutzerkennung, IpHostname ipAdresse,
                              List<String> rollen, Date anmeldezeit, String benutzerEinsatzort) {
    super();
    this.id = id;
    this.sessionId = sessionId;
    this.benutzerPK = benutzerPK;
    this.mandantNummer = mandantNummer;
    this.benutzerkennung = benutzerkennung;
    this.ipAdresse = ipAdresse;
    this.rollen = rollen;
    this.anmeldezeit = anmeldezeit;
    this.benutzerEinsatzort = benutzerEinsatzort;
    letzteInteraktion.set(anmeldezeit.getTime());
  }

  public Date getLetzteInteraktion() {
    return new Date(letzteInteraktion.get());
  }

  public void interact() {
    letzteInteraktion.set(System.currentTimeMillis());
  }

  public String getBenutzerkennung() {
    return benutzerkennung;
  }

  public Date getAnmeldezeit() {
    return anmeldezeit;
  }

  public List<String> getRollen() {
    return rollen;
  }

  public String getRollenAsString() {
    return String.join(", ", getRollen());
  }

  public IpHostname getIpAdresse() {
    return ipAdresse;
  }

  public String getBenutzerEinsatzort() {
    return benutzerEinsatzort;
  }

  public String getSessionIdGui() {
    return StringUtils.abbreviate(getSessionId(), 10);
  }

  public String getNameSessionIdGui() {
    return getBenutzerkennung() + " (" + getSessionIdGui() + ")";
  }

  @Override
  public int compareTo(AngemeldeterBenutzer o) {
    return getId().compareTo(o.getId());
  }

  @Override
  public EntityLongPK getPk() {
    EntityLongPK result = new EntityLongPK();
    result.setId(id);
    return result;
  }

  @Override
  public Long getId() {
    return id;
  }

  @Override
  public EntityUK getUk() {
    return null;
  }

  @Override
  public Class<?> getEntityClass() {
    return getClass();
  }

  @Override
  public String getEntityTechnicalName() {
    throw new UnsupportedOperationException();
  }

  @Override
  public boolean isAenderungenProtokollieren() {
    return false;
  }

  @Override
  public Map<String, VorherNachherWert> getProtokollierteAttributeMitWerten() {
    throw new UnsupportedOperationException();
  }

  @Override
  public void setProtokollierteAttributeMitWerten(Map<String, AttributWertVorher> werteVorher) {
    throw new UnsupportedOperationException();
  }

  @Override
  public void resetProtokollierteAttribute() {
  }

  public Long getMandantNummer() {
    return mandantNummer;
  }

  @Override
  public List<EntityFachlichAbhaengigNode> getFachlichAbhaengigeEntitaeten() {
    throw new UnsupportedOperationException();
  }

  @Override
  public boolean isInstanceOf(Class<?> clazz) {
    return false;
  }

  @Override
  public <E> EntityContainer<E> castTo(Class<E> clazz) {
    throw new UnsupportedOperationException();
  }

  @Override
  public EntityTK getTk() {
    throw new UnsupportedOperationException();
  }

  @Override
  public String getBaseClassName() {
    return getClass().getName();
  }

  @Override
  public void copyEntityAttributesToOtherEntity(Entity other) {
    throw new UnsupportedOperationException();
  }

  public BenutzerPK getBenutzerPK() {
    return benutzerPK;
  }

  @Override
  public boolean equals(Object o) {
    if (this == o) return true;
    if (o == null || getClass() != o.getClass()) return false;

    AngemeldeterBenutzer that = (AngemeldeterBenutzer) o;

    return sessionId.equals(that.sessionId);
  }

  @Override
  public int hashCode() {
    return sessionId.hashCode();
  }

  public String getSessionId() {
    return sessionId;
  }

  @Override
  public String toString() {
    return "AngemeldeterBenutzer{" +
        "id=" + id +
        ", benutzerPK='" + benutzerPK + '\'' +
        ", mandantNummer='" + mandantNummer + '\'' +
        ", benutzerkennung='" + benutzerkennung + '\'' +
        ", sessionId='" + sessionId + '\'' +
        ", ipAdresse=" + ipAdresse +
        '}';
  }
}
