package com.airlock.iam.admin.domain.service.contextdata;

import com.airlock.iam.admin.api.domain.model.administrator.CurrentAdministrator;
import com.airlock.iam.admin.domain.model.contextdata.AdminRealmContextDataName;
import com.airlock.iam.admin.domain.model.contextdata.UserRealmContextDataName;
import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
import jakarta.inject.Inject;
import java.util.Map;
import java.util.Optional;
import java.util.stream.Collectors;

public final class ContextDataCreateAdminService {
   private final CurrentAdministrator currentAdministrator;
   private final Optional<AdminRealmContextDataName> adminRealmContextDataName;
   private final Optional<UserRealmContextDataName> userRealmContextDataName;

   @Inject
   public ContextDataCreateAdminService(
      CurrentAdministrator currentAdministrator,
      Optional<AdminRealmContextDataName> adminRealmContextDataName,
      Optional<UserRealmContextDataName> userRealmContextDataName
   ) {
      this.currentAdministrator = currentAdministrator;
      this.adminRealmContextDataName = adminRealmContextDataName;
      this.userRealmContextDataName = userRealmContextDataName;
   }

   public Map<String, Object> createContextData() {
      return this.realmContextData()
         .stream()
         .collect(Collectors.toMap(ContextDataCreateAdminService.ContextDataEntry::name, ContextDataCreateAdminService.ContextDataEntry::value));
   }

   private Optional<ContextDataCreateAdminService.ContextDataEntry> realmContextData() {
      return this.adminRealmContextDataName
         .<String>flatMap(contextDataName -> contextDataName.getValidatedValue(this.currentAdministrator))
         .map(adminValue -> new ContextDataCreateAdminService.ContextDataEntry(this.userKeyOrThrow(), adminValue));
   }

   private String userKeyOrThrow() {
      return this.userRealmContextDataName
         .map(UserRealmContextDataName::getContextDataName)
         .orElseThrow(() -> new IllegalStateException("User realm context data name config missing"));
   }

   @SuppressFBWarnings(justification = "generated code")
   public static ContextDataCreateAdminService.ContextDataCreateAdminServiceBuilder builder() {
      return new ContextDataCreateAdminService.ContextDataCreateAdminServiceBuilder();
   }

   @SuppressFBWarnings(justification = "generated code")
   public static class ContextDataCreateAdminServiceBuilder {
      @SuppressFBWarnings(justification = "generated code")
      private CurrentAdministrator currentAdministrator;
      @SuppressFBWarnings(justification = "generated code")
      private Optional<AdminRealmContextDataName> adminRealmContextDataName;
      @SuppressFBWarnings(justification = "generated code")
      private Optional<UserRealmContextDataName> userRealmContextDataName;

      @SuppressFBWarnings(justification = "generated code")
      ContextDataCreateAdminServiceBuilder() {
      }

      @SuppressFBWarnings(justification = "generated code")
      public ContextDataCreateAdminService.ContextDataCreateAdminServiceBuilder currentAdministrator(CurrentAdministrator currentAdministrator) {
         this.currentAdministrator = currentAdministrator;
         return this;
      }

      @SuppressFBWarnings(justification = "generated code")
      public ContextDataCreateAdminService.ContextDataCreateAdminServiceBuilder adminRealmContextDataName(
         Optional<AdminRealmContextDataName> adminRealmContextDataName
      ) {
         this.adminRealmContextDataName = adminRealmContextDataName;
         return this;
      }

      @SuppressFBWarnings(justification = "generated code")
      public ContextDataCreateAdminService.ContextDataCreateAdminServiceBuilder userRealmContextDataName(
         Optional<UserRealmContextDataName> userRealmContextDataName
      ) {
         this.userRealmContextDataName = userRealmContextDataName;
         return this;
      }

      @SuppressFBWarnings(justification = "generated code")
      public ContextDataCreateAdminService build() {
         return new ContextDataCreateAdminService(this.currentAdministrator, this.adminRealmContextDataName, this.userRealmContextDataName);
      }

      @SuppressFBWarnings(justification = "generated code")
      @Override
      public String toString() {
         return "ContextDataCreateAdminService.ContextDataCreateAdminServiceBuilder(currentAdministrator="
            + this.currentAdministrator
            + ", adminRealmContextDataName="
            + this.adminRealmContextDataName
            + ", userRealmContextDataName="
            + this.userRealmContextDataName
            + ")";
      }
   }

   private record ContextDataEntry(String name, Object value) {
   }
}
