package com.airlock.iam.flow.shared.infrastructure.session;

import com.airlock.iam.base.api.domain.model.mapification.MapifiedValues;
import com.airlock.iam.base.domain.model.mapification.MapifiedValuesBuilder;
import com.airlock.iam.base.misc.json.JsonCoding;
import com.airlock.iam.common.domain.model.session.SessionId;
import com.airlock.iam.common.domain.model.session.SessionNonces;
import com.airlock.iam.common.infrastructure.session.SessionNoncesMapifier;
import com.airlock.iam.plugin.api.config.ConfigurationContext;
import com.airlock.iam.system.version.IamVersion;
import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
import java.util.Optional;
import lombok.NonNull;

public record FlowBasedIamSessionValues(
   @NonNull Optional<SessionId> sessionId,
   @NonNull SessionNonces sessionNonces,
   @NonNull MapifiedValues userSession,
   @NonNull Optional<String> statemachine,
   @NonNull IamVersion version,
   @NonNull ConfigurationContext context
) {
   public static final String SESSION_ID_KEY = "sessionId";
   public static final String NONCES_KEY = "nonces";
   public static final String USER_SESSION_KEY = "userSession";
   public static final String STATE_MACHINE_KEY = "stateMachine";
   public static final String IAM_VERSION = "iamVersion";
   public static final String CONTEXT_KEY = "context";

   @SuppressFBWarnings(justification = "generated code")
   public FlowBasedIamSessionValues {
      if (sessionId == null) {
         throw new NullPointerException("sessionId is marked non-null but is null");
      }

      if (sessionNonces == null) {
         throw new NullPointerException("sessionNonces is marked non-null but is null");
      }

      if (userSession == null) {
         throw new NullPointerException("userSession is marked non-null but is null");
      }

      if (statemachine == null) {
         throw new NullPointerException("statemachine is marked non-null but is null");
      }

      if (version == null) {
         throw new NullPointerException("version is marked non-null but is null");
      }

      if (context == null) {
         throw new NullPointerException("context is marked non-null but is null");
      }
   }

   public String serialize() {
      return JsonCoding.toJson(
         MapifiedValuesBuilder.mapifiedValues()
            .putIfPresent("sessionId", this.sessionId.map(SessionId::id))
            .put("nonces", SessionNoncesMapifier.mapifyNonces(this.sessionNonces))
            .put("userSession", this.userSession)
            .putIfPresent("stateMachine", this.statemachine)
            .put("iamVersion", this.version.toFullVersionString())
            .put("context", this.context.toString())
            .build()
            .asMap()
      );
   }
}
