package com.airlock.iam.transactionapproval.domain.model.authenticateduser;

import com.airlock.iam.base.api.domain.model.exception.FailureException;
import com.airlock.iam.base.api.domain.model.mapification.MapifiedValues;
import com.airlock.iam.base.api.domain.model.user.UserId;
import com.airlock.iam.base.domain.model.mapification.MapifiedValuesBuilder;
import com.airlock.iam.flow.shared.api.domain.model.session.UserSessionScopedFlowAttribute;
import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
import java.util.Map;
import lombok.NonNull;

public record AuthenticatedUserAttribute(@NonNull AuthenticatedUser authenticatedUser) implements UserSessionScopedFlowAttribute<AuthenticatedUserAttribute> {
   private static final String ID_KEY = "id";

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

   public AuthenticatedUserAttribute mergeWith(AuthenticatedUserAttribute newAttribute) {
      if (!newAttribute.authenticatedUser().hasSameId(this.authenticatedUser)) {
         throw new FailureException("Cannot change authenticated user");
      } else {
         return newAttribute;
      }
   }

   public AuthenticatedUserAttribute copyAttribute() {
      return new AuthenticatedUserAttribute(this.authenticatedUser);
   }

   public MapifiedValues mapify() {
      return MapifiedValuesBuilder.mapifiedValues().put("id", this.authenticatedUser.id().getValue()).build();
   }

   public static AuthenticatedUserAttribute demapify(MapifiedValues values) {
      return new AuthenticatedUserAttribute(new AuthenticatedUser(UserId.userId((String)values.get("id"))));
   }

   public static AuthenticatedUserAttribute deserializeSessionAttribute(Map<String, String> rawValues) {
      return new AuthenticatedUserAttribute(new AuthenticatedUser(UserId.userId(rawValues.get("id"))));
   }
}
