package com.airlock.iam.saml2.infrastructure.plugin;

import com.airlock.iam.common.api.domain.model.user.UsernameToPropagate;
import com.airlock.iam.elog.api.ELogger;
import com.airlock.iam.elog.api.ELoggerFactory;
import com.airlock.iam.saml2.domain.model.session.FlowFederationSession;
import com.airlock.iam.saml2.domain.model.session.Saml2PropagationAttributes;
import com.sun.identity.saml2.assertion.AssertionFactory;
import com.sun.identity.saml2.assertion.NameID;
import com.sun.identity.saml2.common.SAML2Exception;
import com.sun.identity.saml2.plugins.IDPAccountMapper;

public final class IDPAccountMapperImpl implements IDPAccountMapper {
   private static final ELogger LOG = ELoggerFactory.getLogger(IDPAccountMapperImpl.class);

   @Override
   public NameID getNameID(Object session, String hostEntityID, String remoteEntityID, String realm, String nameIDFormat) throws SAML2Exception {
      LOG.debug("Chosen NameIDFormat for SP \"" + remoteEntityID + "\": " + nameIDFormat);
      UsernameToPropagate userID = FlowFederationSession.toFlowFederationSessionOrThrow(
            session, () -> new SAML2Exception("Session is not of type FlowFederationSession")
         )
         .getPropagationAttributes()
         .map(Saml2PropagationAttributes::getUsernameToPropagate)
         .orElseThrow(
            () -> new SAML2Exception("No username to propagate available (invalid username transformation or wrong configuration of 'Use Different Username'?)")
         );
      NameID nameID = AssertionFactory.getInstance().createNameID();
      nameID.setValue(userID.value());
      nameID.setFormat(nameIDFormat);
      nameID.setNameQualifier(hostEntityID);
      nameID.setSPNameQualifier(remoteEntityID);
      nameID.setSPProvidedID(null);
      return nameID;
   }
}
