package com.airlock.iam.login.application.service.kerberos;

import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
import java.util.Optional;
import lombok.NonNull;
import org.ietf.jgss.GSSContext;

public record KerberosValidationResult(
   @NonNull KerberosValidationResult.Status outcome,
   @NonNull Optional<String> username,
   @NonNull Optional<GSSContext> gssContext,
   @NonNull Optional<byte[]> outputToken
) {
   @SuppressFBWarnings(justification = "generated code")
   public KerberosValidationResult {
      if (outcome == null) {
         throw new NullPointerException("outcome is marked non-null but is null");
      }

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

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

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

   public static KerberosValidationResult success(@NonNull String username) {
      if (username == null) {
         throw new NullPointerException("username is marked non-null but is null");
      } else {
         return new KerberosValidationResult(KerberosValidationResult.Status.SUCCESS, Optional.of(username), Optional.empty(), Optional.empty());
      }
   }

   public static KerberosValidationResult unfinished(@NonNull GSSContext gssContext, byte @NonNull [] outputToken) {
      if (gssContext == null) {
         throw new NullPointerException("gssContext is marked non-null but is null");
      } else if (outputToken == null) {
         throw new NullPointerException("outputToken is marked non-null but is null");
      } else {
         return new KerberosValidationResult(KerberosValidationResult.Status.UNFINISHED, Optional.empty(), Optional.of(gssContext), Optional.of(outputToken));
      }
   }

   public static KerberosValidationResult failed() {
      return new KerberosValidationResult(KerberosValidationResult.Status.FAILED, Optional.empty(), Optional.empty(), Optional.empty());
   }

   public static KerberosValidationResult exception() {
      return new KerberosValidationResult(KerberosValidationResult.Status.EXCEPTION, Optional.empty(), Optional.empty(), Optional.empty());
   }

   public enum Status {
      SUCCESS,
      FAILED,
      UNFINISHED,
      EXCEPTION;
   }
}
