package com.airlock.iam.oauth2.infrastructure.event;

import com.airlock.iam.base.api.domain.model.event.EventType;
import com.airlock.iam.base.api.domain.model.user.UserId;
import com.airlock.iam.base.domain.model.event.EventCreationData;
import com.airlock.iam.common.domain.model.event.AbstractUserEvent;
import com.airlock.iam.oauth2.api.domain.model.AuthorizationServerId;
import com.airlock.iam.oauth2.api.domain.model.OAuth2ClientId;
import com.airlock.iam.oauth2.api.domain.model.OAuth2Scope;
import com.airlock.iam.oauth2.api.domain.model.event.OAuth2UserConsentEvent;
import com.airlock.iam.oauth2.domain.model.event.OAuth2EventTypes;
import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
import java.util.Set;
import lombok.NonNull;

public class OAuth2UserConsentEventImpl extends AbstractUserEvent implements OAuth2UserConsentEvent {
   @NonNull
   private final Set<OAuth2Scope> acceptedScopes;
   @NonNull
   private final Set<OAuth2Scope> deniedScopes;
   @NonNull
   private final Set<OAuth2Scope> alwaysGrantedScopes;
   @NonNull
   private final OAuth2ClientId clientId;
   @NonNull
   private final AuthorizationServerId authorizationServerId;

   public OAuth2UserConsentEventImpl(
      EventCreationData eventCreationData,
      UserId userId,
      @NonNull Set<OAuth2Scope> acceptedScopes,
      @NonNull Set<OAuth2Scope> deniedScopes,
      @NonNull Set<OAuth2Scope> alwaysGrantedScopes,
      @NonNull OAuth2ClientId clientId,
      @NonNull AuthorizationServerId authorizationServerId
   ) {
      super(eventCreationData, "OAuth 2.0 User Consent", userId);
      if (acceptedScopes == null) {
         throw new NullPointerException("acceptedScopes is marked non-null but is null");
      }

      if (deniedScopes == null) {
         throw new NullPointerException("deniedScopes is marked non-null but is null");
      }

      if (alwaysGrantedScopes == null) {
         throw new NullPointerException("alwaysGrantedScopes is marked non-null but is null");
      }

      if (clientId == null) {
         throw new NullPointerException("clientId is marked non-null but is null");
      }

      if (authorizationServerId == null) {
         throw new NullPointerException("authorizationServerId is marked non-null but is null");
      }

      this.acceptedScopes = acceptedScopes;
      this.deniedScopes = deniedScopes;
      this.alwaysGrantedScopes = alwaysGrantedScopes;
      this.clientId = clientId;
      this.authorizationServerId = authorizationServerId;
   }

   @Override
   public EventType type() {
      return OAuth2EventTypes.OAUTH2_USER_CONSENT;
   }

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

   @NonNull
   @SuppressFBWarnings(justification = "generated code")
   @Override
   public Set<OAuth2Scope> acceptedScopes() {
      return this.acceptedScopes;
   }

   @NonNull
   @SuppressFBWarnings(justification = "generated code")
   @Override
   public Set<OAuth2Scope> deniedScopes() {
      return this.deniedScopes;
   }

   @NonNull
   @SuppressFBWarnings(justification = "generated code")
   @Override
   public Set<OAuth2Scope> alwaysGrantedScopes() {
      return this.alwaysGrantedScopes;
   }

   @NonNull
   @SuppressFBWarnings(justification = "generated code")
   @Override
   public OAuth2ClientId clientId() {
      return this.clientId;
   }

   @NonNull
   @SuppressFBWarnings(justification = "generated code")
   @Override
   public AuthorizationServerId authorizationServerId() {
      return this.authorizationServerId;
   }

   @SuppressFBWarnings(justification = "generated code")
   public static class OAuth2UserConsentEventImplBuilder {
      @SuppressFBWarnings(justification = "generated code")
      private EventCreationData eventCreationData;
      @SuppressFBWarnings(justification = "generated code")
      private UserId userId;
      @SuppressFBWarnings(justification = "generated code")
      private Set<OAuth2Scope> acceptedScopes;
      @SuppressFBWarnings(justification = "generated code")
      private Set<OAuth2Scope> deniedScopes;
      @SuppressFBWarnings(justification = "generated code")
      private Set<OAuth2Scope> alwaysGrantedScopes;
      @SuppressFBWarnings(justification = "generated code")
      private OAuth2ClientId clientId;
      @SuppressFBWarnings(justification = "generated code")
      private AuthorizationServerId authorizationServerId;

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

      @SuppressFBWarnings(justification = "generated code")
      public OAuth2UserConsentEventImpl.OAuth2UserConsentEventImplBuilder eventCreationData(EventCreationData eventCreationData) {
         this.eventCreationData = eventCreationData;
         return this;
      }

      @SuppressFBWarnings(justification = "generated code")
      public OAuth2UserConsentEventImpl.OAuth2UserConsentEventImplBuilder userId(UserId userId) {
         this.userId = userId;
         return this;
      }

      @SuppressFBWarnings(justification = "generated code")
      public OAuth2UserConsentEventImpl.OAuth2UserConsentEventImplBuilder acceptedScopes(@NonNull Set<OAuth2Scope> acceptedScopes) {
         if (acceptedScopes == null) {
            throw new NullPointerException("acceptedScopes is marked non-null but is null");
         }

         this.acceptedScopes = acceptedScopes;
         return this;
      }

      @SuppressFBWarnings(justification = "generated code")
      public OAuth2UserConsentEventImpl.OAuth2UserConsentEventImplBuilder deniedScopes(@NonNull Set<OAuth2Scope> deniedScopes) {
         if (deniedScopes == null) {
            throw new NullPointerException("deniedScopes is marked non-null but is null");
         }

         this.deniedScopes = deniedScopes;
         return this;
      }

      @SuppressFBWarnings(justification = "generated code")
      public OAuth2UserConsentEventImpl.OAuth2UserConsentEventImplBuilder alwaysGrantedScopes(@NonNull Set<OAuth2Scope> alwaysGrantedScopes) {
         if (alwaysGrantedScopes == null) {
            throw new NullPointerException("alwaysGrantedScopes is marked non-null but is null");
         }

         this.alwaysGrantedScopes = alwaysGrantedScopes;
         return this;
      }

      @SuppressFBWarnings(justification = "generated code")
      public OAuth2UserConsentEventImpl.OAuth2UserConsentEventImplBuilder clientId(@NonNull OAuth2ClientId clientId) {
         if (clientId == null) {
            throw new NullPointerException("clientId is marked non-null but is null");
         }

         this.clientId = clientId;
         return this;
      }

      @SuppressFBWarnings(justification = "generated code")
      public OAuth2UserConsentEventImpl.OAuth2UserConsentEventImplBuilder authorizationServerId(@NonNull AuthorizationServerId authorizationServerId) {
         if (authorizationServerId == null) {
            throw new NullPointerException("authorizationServerId is marked non-null but is null");
         }

         this.authorizationServerId = authorizationServerId;
         return this;
      }

      @SuppressFBWarnings(justification = "generated code")
      public OAuth2UserConsentEventImpl build() {
         return new OAuth2UserConsentEventImpl(
            this.eventCreationData, this.userId, this.acceptedScopes, this.deniedScopes, this.alwaysGrantedScopes, this.clientId, this.authorizationServerId
         );
      }

      @SuppressFBWarnings(justification = "generated code")
      @Override
      public String toString() {
         return "OAuth2UserConsentEventImpl.OAuth2UserConsentEventImplBuilder(eventCreationData="
            + this.eventCreationData
            + ", userId="
            + this.userId
            + ", acceptedScopes="
            + this.acceptedScopes
            + ", deniedScopes="
            + this.deniedScopes
            + ", alwaysGrantedScopes="
            + this.alwaysGrantedScopes
            + ", clientId="
            + this.clientId
            + ", authorizationServerId="
            + this.authorizationServerId
            + ")";
      }
   }
}
