package com.airlock.iam.oauth2.domain.service.scopepolicy;

import com.airlock.iam.elog.api.ELogger;
import com.airlock.iam.elog.api.ELoggerFactory;
import com.airlock.iam.oauth2.api.domain.model.OAuth2Scope;
import com.airlock.iam.oauth2.domain.model.scopepolicy.ScopePolicyInput;
import java.util.Collections;
import java.util.List;
import java.util.stream.Collectors;

public final class ScopePolicyEmptyScopesAllowed implements ScopePolicy {
   private static final ELogger LOG = ELoggerFactory.getLogger(ScopePolicyEmptyScopesAllowed.class);

   @Override
   public boolean isValidRequestedScope(List<OAuth2Scope> requestedScopes) {
      return true;
   }

   @Override
   public List<OAuth2Scope> processScopes(ScopePolicyInput scopesToProcess) {
      if (scopesToProcess.requestedScopes().isEmpty()) {
         return Collections.emptyList();
      }

      if (!scopesToProcess.allowedScopes().isFilterRequestedScopes()) {
         return scopesToProcess.requestedScopes();
      }

      List<OAuth2Scope> explicitlyAllowedScopes = scopesToProcess.allowedScopes().explicitlyAllowedScopes();
      if (explicitlyAllowedScopes.isEmpty()) {
         LOG.debug("Client has no allowed/default scopes; ignoring the requested scopes");
         return Collections.emptyList();
      }

      List<OAuth2Scope> filteredScopes = scopesToProcess.requestedScopes().stream().filter(explicitlyAllowedScopes::contains).collect(Collectors.toList());
      if (filteredScopes.size() != scopesToProcess.requestedScopes().size()) {
         LOG.debug(
            "Filtered the requested scopes %s against the allowed scopes of this client, resulting in %s"
               .formatted(ScopePolicy.toScopeString(scopesToProcess.requestedScopes()), ScopePolicy.toScopeString(filteredScopes))
         );
      }

      return filteredScopes;
   }
}
