package com.airlock.iam.authentication.infrastructure.resource;

import com.airlock.iam.base.api.domain.model.user.UserId;
import com.airlock.iam.common.api.domain.model.user.UserIdentity;
import com.airlock.iam.common.api.infrastructure.annotation.DisableSystemAvailabilityCheck;
import com.airlock.iam.common.domain.model.user.PrincipalInfo;
import com.airlock.iam.flow.application.service.flow.FlowTerminationService;
import com.airlock.iam.log.api.helpdesk.HelpdeskLogger;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.responses.ApiResponse;
import jakarta.inject.Inject;
import jakarta.inject.Provider;
import jakarta.ws.rs.DELETE;
import jakarta.ws.rs.Path;
import jakarta.ws.rs.Produces;
import jakarta.ws.rs.core.Response;
import java.util.Optional;

@Path("/flow")
public final class CurrentAuthenticationFlowResource {
   private final HelpdeskLogger helpdeskLogger;
   private final Provider<PrincipalInfo> principalInfo;
   private final Provider<FlowTerminationService> flowTerminationService;

   @Inject
   public CurrentAuthenticationFlowResource(
      HelpdeskLogger helpdeskLogger, Provider<PrincipalInfo> principalInfo, Provider<FlowTerminationService> flowTerminationService
   ) {
      this.helpdeskLogger = helpdeskLogger;
      this.principalInfo = principalInfo;
      this.flowTerminationService = flowTerminationService;
   }

   @ApiResponse(responseCode = "204", description = "Authentication flow successfully terminated.")
   @Operation(
      description = "Aborts the current authentication flow.\nDoes not terminate an already authenticated user session.\n<div class=\"iam-resource-return\">the response</div>",
      tags = "Flow Control",
      summary = "Abort flow"
   )
   @DELETE
   @Produces({"application/vnd.api+json", "application/json;qs=0.9"})
   @DisableSystemAvailabilityCheck
   public Response abort() {
      Optional<UserId> userId = ((PrincipalInfo)this.principalInfo.get()).getKnownIdentity().map(UserIdentity::id);
      if (((FlowTerminationService)this.flowTerminationService.get()).abortFlow()) {
         this.helpdeskLogger.log(userId.orElse(null), "Authentication flow aborted.");
      }

      return Response.noContent().build();
   }
}
