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.List;
import java.util.stream.Collectors;

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

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

   @Override
   public List<OAuth2Scope> processScopes(ScopePolicyInput scopesToProcess) {
      List<OAuth2Scope> explicitlyAllowedScopes = scopesToProcess.allowedScopes().explicitlyAllowedScopes();
      if (scopesToProcess.requestedScopes().isEmpty()) {
         if (!explicitlyAllowedScopes.isEmpty()) {
            LOG.debug("Client requested no scopes, using his explicitly allowed scopes" + ScopePolicy.toScopeString(explicitlyAllowedScopes));
         }

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

         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;
      }
   }
}
