package com.airlock.iam.ssi.application.configuration.procivis;

import com.airlock.iam.common.api.application.configuration.valueprovider.StringValueProviderConfig;
import com.airlock.iam.core.misc.plugin.config.validation.UriPropertyValidator;
import com.airlock.iam.core.misc.util.httpclient.HttpClientConfig;
import com.airlock.iam.plugin.api.annotation.config.ConfigurationValidator;
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.PluginProperty;
import com.airlock.iam.plugin.api.annotation.property.StringProperty;
import com.airlock.iam.plugin.api.config.ConfigurationContext;
import com.airlock.iam.plugin.api.config.ConfigurationEnvironment;
import com.airlock.iam.plugin.api.config.Environment;
import com.airlock.iam.plugin.api.config.PluginConfiguration;
import com.airlock.iam.plugin.api.exception.ConfigurationException;
import com.airlock.iam.ssi.application.configuration.SsiServiceConfig;
import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
import java.net.URI;

@Plugin(description = "SSI service using Procivis One Desk.", displayName = "Procivis One Desk SSI Service")
@PluginLicenseRestriction(moduleAffiliation = "AirlockIAM")
public final class ProcivisDeskSsiServiceConfig implements SsiServiceConfig {
   @StringProperty(
      description = "The URL where the Procivis One Desk API can be reached.",
      displayName = "Procivis One Desk URL",
      exampleValues = "https://desk.trial.procivis-one.com",
      optional = false
   )
   private String procivisUrl;
   private static final String PROCIVIS_URL_FIELD = "procivisUrl";
   private static final String PROCIVIS_URL = "Procivis One Desk URL";
   @StringProperty(
      description = "The DID to use as identifier of IAM as initiator of proof requests or to issue credentials.\n<p>This DID must exist in Procivis One Desk.</p>",
      displayName = "Issuer / Verifier DID",
      exampleValues = "did:key:zDnaedCJsgVRW7Ap4p7fa8squDoX5h4SVJ5EjdeQ3pZNw73nQ",
      optional = false
   )
   private String issuerVerifierDid;
   @StringProperty(
      description = "The issuance protocol to use when communicating with wallets.\n<p>This is dependent on the configuration of the Procivis One Desk.</p>",
      defaultValue = "OPENID4VCI",
      suggestedValues = {"OPENID4VC", "OPENID4VCI_DRAFT13", "OPENID4VCI_DRAFT13_SWIYU"},
      optional = true
   )
   private String issuanceProtocol;
   @StringProperty(
      description = "The verification protocol to use when communicating with wallets.\n<p>This is dependent on the configuration of the Procivis One Desk.</p>",
      defaultValue = "OPENID4VP",
      suggestedValues = {"OPENID4VC", "OPENID4VP_DRAFT20", "OPENID4VP_DRAFT20_SWIYU"},
      optional = true
   )
   private String verificationProtocol;
   @PluginProperty(description = "The HTTP client to use for communicating with the Procivis instance.", displayName = "HTTP Client", optional = false)
   private HttpClientConfig httpClient;
   @PluginProperty(description = "Provides an Access Token for authorization to the Procivis One Desk.", optional = false)
   private StringValueProviderConfig accessTokenProvider;

   @ConfigurationValidator
   static void validateUrl(PluginConfiguration config, ConfigurationEnvironment env, ConfigurationContext context, Environment validationEnvironment) throws ConfigurationException {
      UriPropertyValidator.uriPropertyValidator("procivisUrl", "Procivis One Desk URL", config, env, context).validateIsAbsolute();
   }

   public URI getProcivisUrl() {
      return URI.create(this.procivisUrl);
   }

   public String getIssuerVerifierDid() {
      return this.issuerVerifierDid;
   }

   public String getIssuanceProtocol() {
      return this.issuanceProtocol;
   }

   public String getVerificationProtocol() {
      return this.verificationProtocol;
   }

   public HttpClientConfig getHttpClient() {
      return this.httpClient;
   }

   public StringValueProviderConfig getAccessTokenProvider() {
      return this.accessTokenProvider;
   }

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

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

   @SuppressFBWarnings(justification = "generated code")
   public ProcivisDeskSsiServiceConfig(
      String procivisUrl,
      String issuerVerifierDid,
      String issuanceProtocol,
      String verificationProtocol,
      HttpClientConfig httpClient,
      StringValueProviderConfig accessTokenProvider
   ) {
      this.procivisUrl = procivisUrl;
      this.issuerVerifierDid = issuerVerifierDid;
      this.issuanceProtocol = issuanceProtocol;
      this.verificationProtocol = verificationProtocol;
      this.httpClient = httpClient;
      this.accessTokenProvider = accessTokenProvider;
   }

   @SuppressFBWarnings(justification = "generated code")
   public static class ProcivisDeskSsiServiceConfigBuilder {
      @SuppressFBWarnings(justification = "generated code")
      private String procivisUrl;
      @SuppressFBWarnings(justification = "generated code")
      private String issuerVerifierDid;
      @SuppressFBWarnings(justification = "generated code")
      private String issuanceProtocol;
      @SuppressFBWarnings(justification = "generated code")
      private String verificationProtocol;
      @SuppressFBWarnings(justification = "generated code")
      private HttpClientConfig httpClient;
      @SuppressFBWarnings(justification = "generated code")
      private StringValueProviderConfig accessTokenProvider;

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

      @SuppressFBWarnings(justification = "generated code")
      public ProcivisDeskSsiServiceConfig.ProcivisDeskSsiServiceConfigBuilder procivisUrl(String procivisUrl) {
         this.procivisUrl = procivisUrl;
         return this;
      }

      @SuppressFBWarnings(justification = "generated code")
      public ProcivisDeskSsiServiceConfig.ProcivisDeskSsiServiceConfigBuilder issuerVerifierDid(String issuerVerifierDid) {
         this.issuerVerifierDid = issuerVerifierDid;
         return this;
      }

      @SuppressFBWarnings(justification = "generated code")
      public ProcivisDeskSsiServiceConfig.ProcivisDeskSsiServiceConfigBuilder issuanceProtocol(String issuanceProtocol) {
         this.issuanceProtocol = issuanceProtocol;
         return this;
      }

      @SuppressFBWarnings(justification = "generated code")
      public ProcivisDeskSsiServiceConfig.ProcivisDeskSsiServiceConfigBuilder verificationProtocol(String verificationProtocol) {
         this.verificationProtocol = verificationProtocol;
         return this;
      }

      @SuppressFBWarnings(justification = "generated code")
      public ProcivisDeskSsiServiceConfig.ProcivisDeskSsiServiceConfigBuilder httpClient(HttpClientConfig httpClient) {
         this.httpClient = httpClient;
         return this;
      }

      @SuppressFBWarnings(justification = "generated code")
      public ProcivisDeskSsiServiceConfig.ProcivisDeskSsiServiceConfigBuilder accessTokenProvider(StringValueProviderConfig accessTokenProvider) {
         this.accessTokenProvider = accessTokenProvider;
         return this;
      }

      @SuppressFBWarnings(justification = "generated code")
      public ProcivisDeskSsiServiceConfig build() {
         return new ProcivisDeskSsiServiceConfig(
            this.procivisUrl, this.issuerVerifierDid, this.issuanceProtocol, this.verificationProtocol, this.httpClient, this.accessTokenProvider
         );
      }

      @SuppressFBWarnings(justification = "generated code")
      @Override
      public String toString() {
         return "ProcivisDeskSsiServiceConfig.ProcivisDeskSsiServiceConfigBuilder(procivisUrl="
            + this.procivisUrl
            + ", issuerVerifierDid="
            + this.issuerVerifierDid
            + ", issuanceProtocol="
            + this.issuanceProtocol
            + ", verificationProtocol="
            + this.verificationProtocol
            + ", httpClient="
            + this.httpClient
            + ", accessTokenProvider="
            + this.accessTokenProvider
            + ")";
      }
   }
}
