package com.airlock.iam.oauth2.domain.model.codegrant;

import com.airlock.iam.base.api.domain.model.plugin.LogicForConfig;
import com.airlock.iam.common.api.domain.model.role.Role;
import com.airlock.iam.common.api.domain.model.user.User;
import com.airlock.iam.flow.api.domain.model.tag.CurrentFlowTags;
import com.airlock.iam.flow.api.domain.model.tag.TagName;
import com.airlock.iam.oauth2.api.domain.model.provider.scope.OAuth2ScopeCondition;
import com.airlock.iam.oauth2.application.configuration.OAuth2DefaultScopesSettingsConfig;
import jakarta.inject.Inject;
import jakarta.inject.Provider;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;
import java.util.stream.Stream;

@LogicForConfig(OAuth2DefaultScopesSettingsConfig.class)
public final class OAuth2DefaultScopesSettings implements OAuth2ScopesSettings {
   private final Provider<CurrentFlowTags> currentTags;
   private final User user;

   @Inject
   public OAuth2DefaultScopesSettings(Provider<CurrentFlowTags> currentTags, User user) {
      this.currentTags = currentTags;
      this.user = user;
   }

   @Override
   public List<OAuth2ScopeCondition> scopeConditions() {
      return List.of(scope -> this.rolesAndTags().contains(scope.name()));
   }

   private Set<String> rolesAndTags() {
      return Stream.concat(this.tagsStream(), this.rolesStream()).collect(Collectors.toSet());
   }

   private Stream<String> rolesStream() {
      return this.user.getRoles().stream().map(Role::getRoleName);
   }

   private Stream<String> tagsStream() {
      return ((CurrentFlowTags)this.currentTags.get()).getCurrentTagNames().stream().map(TagName::name);
   }
}
