package com.airlock.iam.oauth2.application.configuration.client;

import com.airlock.iam.core.domain.model.http.client.HttpClient;
import com.airlock.iam.elog.api.ELogger;
import com.airlock.iam.oauth2.domain.model.client.communication.OAuth2ClientResourceRequestLogic;
import com.airlock.iam.oauth2.domain.model.client.communication.OAuth2ResourceRequestSecretProcessor;
import com.airlock.iam.plugin.api.annotation.config.Plugin;
import com.airlock.iam.plugin.api.annotation.license.PluginLicenseRestriction;
import com.airlock.iam.plugin.api.annotation.property.PluginListProperty;
import com.airlock.iam.plugin.api.annotation.property.PluginProperty;
import com.airlock.iam.plugin.api.annotation.property.StringProperty;
import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
import java.net.URI;
import java.util.List;

@Plugin(
   description = "Represents a resource request executed during OAuth 2.0 SSO in order to fetch information about the identity of the user on the provider.",
   displayName = "OAuth 2.0 SSO Resource Request"
)
@PluginLicenseRestriction(moduleAffiliation = "OAuthClient")
public class OAuth2ClientResourceRequest {
   @StringProperty(
      description = "Resource URL to the protected resources.",
      optional = false,
      exampleValues = {
            "https://airlock.iam/auth/rest/oauth2/authorization-servers/myAS/resources/myResource",
            "https://www.googleapis.com/plus/v1/people/me",
            "https://apis.live.net/v5.0/me"
      }
   )
   private String resourceURL;
   @PluginListProperty(description = "List of remote resources that will be included in the response to this request.", optional = false, minElements = 1)
   private List<AbstractOAuth2RemoteResourceConfig> containedResources;
   public static final String CONTAINED_RESOURCES_FIELD = "containedResources";
   @PluginProperty(description = "HTTP method to use for this request.", optional = true, defaultValue = OAuth2GetRequestBuilderConfig.class)
   private OAuth2RequestBuilderConfig requestMethod;
   @PluginProperty(description = "Specifies the Access Token format for resource requests.", optional = false)
   private OAuth2ResourceRequestSecretProcessor accessTokenConfig;

   public OAuth2ClientResourceRequestLogic logic(ELogger logger, HttpClient httpClient) {
      return OAuth2ClientResourceRequestLogic.builder()
         .logger(logger)
         .httpClientInstance(httpClient)
         .resourceURI(URI.create(this.resourceURL))
         .resources(this.containedResources.stream().map(AbstractOAuth2RemoteResourceConfig::resource).toList())
         .requestMethod(this.requestMethod.logic())
         .secretProcessor(this.accessTokenConfig)
         .build();
   }

   @SuppressFBWarnings(justification = "generated code")
   public static OAuth2ClientResourceRequest.OAuth2ClientResourceRequestBuilder builder() {
      return new OAuth2ClientResourceRequest.OAuth2ClientResourceRequestBuilder();
   }

   @SuppressFBWarnings(justification = "generated code")
   public OAuth2ClientResourceRequest(
      String resourceURL,
      List<AbstractOAuth2RemoteResourceConfig> containedResources,
      OAuth2RequestBuilderConfig requestMethod,
      OAuth2ResourceRequestSecretProcessor accessTokenConfig
   ) {
      this.resourceURL = resourceURL;
      this.containedResources = containedResources;
      this.requestMethod = requestMethod;
      this.accessTokenConfig = accessTokenConfig;
   }

   @SuppressFBWarnings(justification = "generated code")
   public OAuth2ClientResourceRequest() {
   }

   @SuppressFBWarnings(justification = "generated code")
   public static class OAuth2ClientResourceRequestBuilder {
      @SuppressFBWarnings(justification = "generated code")
      private String resourceURL;
      @SuppressFBWarnings(justification = "generated code")
      private List<AbstractOAuth2RemoteResourceConfig> containedResources;
      @SuppressFBWarnings(justification = "generated code")
      private OAuth2RequestBuilderConfig requestMethod;
      @SuppressFBWarnings(justification = "generated code")
      private OAuth2ResourceRequestSecretProcessor accessTokenConfig;

      @SuppressFBWarnings(justification = "generated code")
      OAuth2ClientResourceRequestBuilder() {
      }

      @SuppressFBWarnings(justification = "generated code")
      public OAuth2ClientResourceRequest.OAuth2ClientResourceRequestBuilder resourceURL(String resourceURL) {
         this.resourceURL = resourceURL;
         return this;
      }

      @SuppressFBWarnings(justification = "generated code")
      public OAuth2ClientResourceRequest.OAuth2ClientResourceRequestBuilder containedResources(List<AbstractOAuth2RemoteResourceConfig> containedResources) {
         this.containedResources = containedResources;
         return this;
      }

      @SuppressFBWarnings(justification = "generated code")
      public OAuth2ClientResourceRequest.OAuth2ClientResourceRequestBuilder requestMethod(OAuth2RequestBuilderConfig requestMethod) {
         this.requestMethod = requestMethod;
         return this;
      }

      @SuppressFBWarnings(justification = "generated code")
      public OAuth2ClientResourceRequest.OAuth2ClientResourceRequestBuilder accessTokenConfig(OAuth2ResourceRequestSecretProcessor accessTokenConfig) {
         this.accessTokenConfig = accessTokenConfig;
         return this;
      }

      @SuppressFBWarnings(justification = "generated code")
      public OAuth2ClientResourceRequest build() {
         return new OAuth2ClientResourceRequest(this.resourceURL, this.containedResources, this.requestMethod, this.accessTokenConfig);
      }

      @SuppressFBWarnings(justification = "generated code")
      @Override
      public String toString() {
         return "OAuth2ClientResourceRequest.OAuth2ClientResourceRequestBuilder(resourceURL="
            + this.resourceURL
            + ", containedResources="
            + this.containedResources
            + ", requestMethod="
            + this.requestMethod
            + ", accessTokenConfig="
            + this.accessTokenConfig
            + ")";
      }
   }
}
