package com.airlock.iam.authentication.application.configuration.ui;

import com.airlock.iam.authentication.api.application.configuration.password.UsernamePasswordAuthStepConfig;
import com.airlock.iam.authentication.application.configuration.airlock2fa.Airlock2FAUsernamelessQrCodeAuthenticationStepConfig;
import com.airlock.iam.authentication.application.configuration.fido.FidoPasswordlessAuthenticationStepConfig;
import com.airlock.iam.authentication.application.configuration.identification.UserIdentifyingFidoStepConfig;
import com.airlock.iam.authentication.application.configuration.password.PasswordAuthenticationStepConfig;
import com.airlock.iam.flow.api.application.configuration.step.StepIdConfig;
import com.airlock.iam.flow.api.domain.model.step.StepId;
import com.airlock.iam.flow.shared.application.configuration.identification.UserIdentifyingStepConfig;
import com.airlock.iam.flow.ui.application.configuration.PublicSelfServiceLinkConfig;
import com.airlock.iam.flow.ui.application.configuration.UserSelfRegLinkConfig;
import com.airlock.iam.flow.ui.infrastructure.settings.annotation.UiForStep;
import com.airlock.iam.flow.ui.infrastructure.settings.annotation.UiForSteps;
import com.airlock.iam.login.application.configuration.targetapp.ApplicationIdConfig;
import com.airlock.iam.plugin.api.annotation.config.Plugin;
import com.airlock.iam.plugin.api.annotation.license.PluginPropertyLicenseRestriction;
import com.airlock.iam.plugin.api.annotation.property.PluginListProperty;
import com.airlock.iam.plugin.api.annotation.property.PluginProperty;
import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
import jakarta.annotation.Nullable;
import java.util.List;

@Plugin(
   description = "User interface configuration for adding links and buttons to authentication flow steps. This is supported for:<ol><li>Username Password Authentication Step</li><li>Username Password with FIDO Authentication Step</li><li>User Identification Step</li><li>Password-only Authentication Step</li><li>FIDO Passwordless Authentication Step</li><li>Airlock 2FA Usernameless Authentication Step</li></ol>",
   displayName = "Link Configuration Authentication UI"
)
@UiForSteps(
   {
         @UiForStep(UsernamePasswordAuthStepConfig.class),
         @UiForStep(UserIdentifyingStepConfig.class),
         @UiForStep(UserIdentifyingFidoStepConfig.class),
         @UiForStep(PasswordAuthenticationStepConfig.class),
         @UiForStep(FidoPasswordlessAuthenticationStepConfig.class),
         @UiForStep(Airlock2FAUsernamelessQrCodeAuthenticationStepConfig.class)
   }
)
public final class LinkConfigurationAuthenticationStepUiConfig implements AuthenticationStepUiConfig {
   @PluginProperty(description = "The ID of the step to which this user interface is referring.", displayName = "Step ID", optional = false)
   private StepIdConfig stepId;
   @PluginProperty(description = "The user self-registration link to display on the page.", displayName = "User Self-Registration Link", optional = true)
   @PluginPropertyLicenseRestriction(moduleAffiliation = "SelfRegistration")
   private UserSelfRegLinkConfig userSelfRegistrationLink;
   public static final String SELF_REG_LINK_PROPERTY = "userSelfRegistrationLink";
   @PluginProperty(
      description = "Link to a public self-service to display on the page, e.g. for password reset.",
      displayName = "Public Self-Service Link",
      optional = true
   )
   private PublicSelfServiceLinkConfig publicSelfServiceLink;
   public static final String PUBLIC_SELF_SERVICE_LINK_PROPERTY = "publicSelfServiceLink";
   @PluginListProperty(
      description = "A list of additional flows to display on the page. Can be used to reference SSO (e.g. OAuth 2.0 / OpenId Connect) flows that can be started to authenticate the user.",
      displayName = "Additional Authentication Buttons",
      minElements = 1,
      optional = true
   )
   private List<ApplicationIdConfig> additionalAuthenticationButtons;
   public static final String ADDITIONAL_AUTHENTICATION_FLOWS_PROPERTY = "additionalAuthenticationButtons";

   public StepId getStepId() {
      return this.stepId.getId();
   }

   @Nullable
   public UserSelfRegLinkConfig getUserSelfRegistrationLink() {
      return this.userSelfRegistrationLink;
   }

   @Nullable
   public PublicSelfServiceLinkConfig getPublicSelfServiceLink() {
      return this.publicSelfServiceLink;
   }

   public List<ApplicationIdConfig> getAdditionalAuthenticationButtons() {
      return this.additionalAuthenticationButtons;
   }

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

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

   @SuppressFBWarnings(justification = "generated code")
   public LinkConfigurationAuthenticationStepUiConfig(
      StepIdConfig stepId,
      UserSelfRegLinkConfig userSelfRegistrationLink,
      PublicSelfServiceLinkConfig publicSelfServiceLink,
      List<ApplicationIdConfig> additionalAuthenticationButtons
   ) {
      this.stepId = stepId;
      this.userSelfRegistrationLink = userSelfRegistrationLink;
      this.publicSelfServiceLink = publicSelfServiceLink;
      this.additionalAuthenticationButtons = additionalAuthenticationButtons;
   }

   @SuppressFBWarnings(justification = "generated code")
   public static class LinkConfigurationAuthenticationStepUiConfigBuilder {
      @SuppressFBWarnings(justification = "generated code")
      private StepIdConfig stepId;
      @SuppressFBWarnings(justification = "generated code")
      private UserSelfRegLinkConfig userSelfRegistrationLink;
      @SuppressFBWarnings(justification = "generated code")
      private PublicSelfServiceLinkConfig publicSelfServiceLink;
      @SuppressFBWarnings(justification = "generated code")
      private List<ApplicationIdConfig> additionalAuthenticationButtons;

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

      @SuppressFBWarnings(justification = "generated code")
      public LinkConfigurationAuthenticationStepUiConfig.LinkConfigurationAuthenticationStepUiConfigBuilder stepId(StepIdConfig stepId) {
         this.stepId = stepId;
         return this;
      }

      @SuppressFBWarnings(justification = "generated code")
      public LinkConfigurationAuthenticationStepUiConfig.LinkConfigurationAuthenticationStepUiConfigBuilder userSelfRegistrationLink(
         UserSelfRegLinkConfig userSelfRegistrationLink
      ) {
         this.userSelfRegistrationLink = userSelfRegistrationLink;
         return this;
      }

      @SuppressFBWarnings(justification = "generated code")
      public LinkConfigurationAuthenticationStepUiConfig.LinkConfigurationAuthenticationStepUiConfigBuilder publicSelfServiceLink(
         PublicSelfServiceLinkConfig publicSelfServiceLink
      ) {
         this.publicSelfServiceLink = publicSelfServiceLink;
         return this;
      }

      @SuppressFBWarnings(justification = "generated code")
      public LinkConfigurationAuthenticationStepUiConfig.LinkConfigurationAuthenticationStepUiConfigBuilder additionalAuthenticationButtons(
         List<ApplicationIdConfig> additionalAuthenticationButtons
      ) {
         this.additionalAuthenticationButtons = additionalAuthenticationButtons;
         return this;
      }

      @SuppressFBWarnings(justification = "generated code")
      public LinkConfigurationAuthenticationStepUiConfig build() {
         return new LinkConfigurationAuthenticationStepUiConfig(
            this.stepId, this.userSelfRegistrationLink, this.publicSelfServiceLink, this.additionalAuthenticationButtons
         );
      }

      @SuppressFBWarnings(justification = "generated code")
      @Override
      public String toString() {
         return "LinkConfigurationAuthenticationStepUiConfig.LinkConfigurationAuthenticationStepUiConfigBuilder(stepId="
            + this.stepId
            + ", userSelfRegistrationLink="
            + this.userSelfRegistrationLink
            + ", publicSelfServiceLink="
            + this.publicSelfServiceLink
            + ", additionalAuthenticationButtons="
            + this.additionalAuthenticationButtons
            + ")";
      }
   }
}
