package com.airlock.iam.saml2.domain.model.sp;

import com.airlock.iam.base.api.domain.model.mapification.MapifiedValues;
import com.airlock.iam.base.domain.model.mapification.MapifiedValuesBuilder;
import com.airlock.iam.flow.shared.api.domain.model.session.UserSessionScopedFlowAttribute;
import java.util.Optional;

public record Saml2SpInitiatedSsoSessionAttribute(Saml2SpInitiatedSsoId ssoId, Saml2SpEntityId spEntityId, Optional<Saml2AuthnRequestId> authnRequestId)
   implements UserSessionScopedFlowAttribute<Saml2SpInitiatedSsoSessionAttribute> {
   private static final String SSO_ID_KEY = "ssoId";
   private static final String SP_ENTITY_ID_KEY = "spEntityId";
   private static final String AUTHN_REQUEST_ID_KEY = "authnRequestId";

   public static Saml2SpInitiatedSsoSessionAttribute spInitiatedSsoSessionAttribute(Saml2SpInitiatedSsoId ssoId, Saml2SpEntityId spEntityId) {
      return new Saml2SpInitiatedSsoSessionAttribute(ssoId, spEntityId, Optional.empty());
   }

   public Saml2SpInitiatedSsoSessionAttribute withAuthnRequestId(Saml2AuthnRequestId authnRequestId) {
      return new Saml2SpInitiatedSsoSessionAttribute(this.ssoId, this.spEntityId, Optional.of(authnRequestId));
   }

   public Saml2SpInitiatedSsoSessionAttribute withoutAuthnRequestId() {
      return new Saml2SpInitiatedSsoSessionAttribute(this.ssoId, this.spEntityId, Optional.empty());
   }

   public Saml2SpInitiatedSsoSessionAttribute mergeWith(Saml2SpInitiatedSsoSessionAttribute newAttribute) {
      return newAttribute;
   }

   @Override
   public MapifiedValues mapify() {
      return MapifiedValuesBuilder.mapifiedValues()
         .put("ssoId", this.ssoId.value())
         .put("spEntityId", this.spEntityId.value())
         .putIfPresent("authnRequestId", this.authnRequestId.map(Saml2AuthnRequestId::value))
         .build();
   }

   public static Saml2SpInitiatedSsoSessionAttribute demapify(MapifiedValues values) {
      return new Saml2SpInitiatedSsoSessionAttribute(
         values.simpleValue("ssoId", Saml2SpInitiatedSsoId::parseSpInitiatedSsoId),
         values.simpleValue("spEntityId", Saml2SpEntityId::spEntityId),
         values.<String>getOptional("authnRequestId").map(Saml2AuthnRequestId::parseAuthnRequestId)
      );
   }

   public Saml2SpInitiatedSsoSessionAttribute copyAttribute() {
      return new Saml2SpInitiatedSsoSessionAttribute(this.ssoId, this.spEntityId, this.authnRequestId);
   }
}
