package com.airlock.iam.oauth2.application.service.consent;

import com.airlock.iam.common.api.domain.model.role.Role;
import com.airlock.iam.oauth2.application.configuration.OAuth2ConsentConfig;
import com.airlock.iam.oauth2.application.configuration.OAuth2LocalConsentConfig;
import com.airlock.iam.oauth2.application.configuration.OAuth2RemoteConsentConfig;
import com.airlock.iam.oauth2.domain.model.consent.OAuth2ConsentSettings;
import com.airlock.iam.oauth2.domain.model.consent.OAuth2LocalConsentSettings;
import com.airlock.iam.oauth2.domain.model.consent.OAuth2RemoteConsentSettings;
import java.net.URI;
import java.time.Duration;
import java.util.Optional;

public final class OAuth2ConsentSettingsFactory {
   public static Optional<OAuth2ConsentSettings> consentSettings(Optional<OAuth2ConsentConfig> consentConfig) {
      return consentConfig.map(OAuth2ConsentSettingsFactory::consentSettings);
   }

   public static OAuth2ConsentSettings consentSettings(OAuth2ConsentConfig consentConfig) {
      if (consentConfig instanceof OAuth2LocalConsentConfig) {
         return localConsentSettings();
      } else if (consentConfig instanceof OAuth2RemoteConsentConfig) {
         return remoteConsentSettings((OAuth2RemoteConsentConfig)consentConfig);
      } else {
         throw new IllegalStateException("Unknown OAuth 2.0 consent configuration: " + consentConfig.getClass());
      }
   }

   private static OAuth2LocalConsentSettings localConsentSettings() {
      return OAuth2LocalConsentSettings.builder().build();
   }

   private static OAuth2ConsentSettings remoteConsentSettings(OAuth2RemoteConsentConfig remoteConsentConfig) {
      return OAuth2RemoteConsentSettings.builder()
         .remoteConsentUri(URI.create(remoteConsentConfig.getRemoteConsentUrl()))
         .signer(remoteConsentConfig.getSigner())
         .encrypter(remoteConsentConfig.getEncrypter())
         .validity(Duration.ofSeconds(remoteConsentConfig.getValidity()))
         .callbackUri(URI.create(remoteConsentConfig.getCallbackUrl()))
         .verifier(remoteConsentConfig.getVerifier())
         .decrypter(remoteConsentConfig.getDecrypter())
         .wafCredential(remoteConsentConfig.wafCredential().map(Role::parseRole))
         .build();
   }

   private OAuth2ConsentSettingsFactory() {
      throw new AssertionError();
   }
}
