package com.airlock.iam.techclientreg.domain.model.registration;

import com.airlock.iam.base.api.domain.model.plugin.LogicForConfig;
import com.airlock.iam.base.misc.log.LogUtil;
import com.airlock.iam.elog.api.ELogger;
import com.airlock.iam.elog.api.ELoggerFactory;
import com.airlock.iam.techclient.api.domain.model.oauth2.OAuth2TechnicalClientMetadataBuilder;
import com.airlock.iam.techclientreg.api.domain.model.oauth2.OAuth2ClientRegistrationError;
import com.airlock.iam.techclientreg.api.domain.model.oauth2.OAuth2ClientRegistrationRequest;
import com.airlock.iam.techclientreg.api.domain.service.oauth2.OAuth2ClientMetadataProcessor;
import com.airlock.iam.techclientreg.application.configuration.registration.ContactsProcessorConfig;
import jakarta.inject.Inject;
import jakarta.inject.Provider;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;

@LogicForConfig(ContactsProcessorConfig.class)
public class ContactsProcessor implements OAuth2ClientMetadataProcessor {
   private static final ELogger LOG = ELoggerFactory.getLogger(ContactsProcessor.class);
   private final Provider<ContactsProcessorConfig> config;
   private final ClientMetadataAttributeValidator validator;

   @Inject
   public ContactsProcessor(Provider<ContactsProcessorConfig> config, ClientMetadataAttributeValidator validator) {
      this.config = config;
      this.validator = validator;
   }

   @Override
   public Optional<OAuth2ClientRegistrationError> updateClient(OAuth2ClientRegistrationRequest request, OAuth2TechnicalClientMetadataBuilder clientBuilder) {
      List<String> contacts = this.extractValidContacts(request);
      if (contacts.isEmpty() && ((ContactsProcessorConfig)this.config.get()).isMandatory()) {
         return Optional.of(OAuth2ClientRegistrationError.invalidClientMetadata("contacts missing or invalid"));
      }

      if (!contacts.isEmpty()) {
         LOG.debug("Using contacts received from the client: " + LogUtil.logSafeString(String.join(", ", contacts)));
         clientBuilder.contacts(contacts);
      }

      return Optional.empty();
   }

   private List<String> extractValidContacts(OAuth2ClientRegistrationRequest request) {
      return request.getMetadata().contacts().stream().filter(this::isValidContact).collect(Collectors.toList());
   }

   private boolean isValidContact(String contact) {
      return this.validator.isValidMetadataAttribute("contacts", contact, 200, ((ContactsProcessorConfig)this.config.get()).getAllowedContacts());
   }
}
