package com.airlock.iam.admin.infrastructure.resource.prot.techclient;

import com.airlock.iam.base.infrastructure.error.ErrorResponse;
import com.airlock.iam.common.domain.model.identity.DefaultStringIdentity;
import com.airlock.iam.techclient.admin.application.service.ApiKeyService;
import com.airlock.iam.techclient.admin.domain.model.ApiKey;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.media.Content;
import io.swagger.v3.oas.annotations.media.Schema;
import io.swagger.v3.oas.annotations.responses.ApiResponse;
import io.swagger.v3.oas.annotations.responses.ApiResponses;
import jakarta.inject.Inject;
import jakarta.inject.Provider;
import jakarta.ws.rs.DELETE;
import jakarta.ws.rs.POST;
import jakarta.ws.rs.Path;
import jakarta.ws.rs.PathParam;
import jakarta.ws.rs.Produces;
import jakarta.ws.rs.core.Response;
import jakarta.ws.rs.core.Response.Status;
import java.util.Optional;

@Path("/api-keys/{apiKeyId}/lock")
public class ApiKeyLockResource {
   private final Provider<ApiKeyService> apiKeyService;

   @Inject
   public ApiKeyLockResource(Provider<ApiKeyService> apiKeyService) {
      this.apiKeyService = apiKeyService;
   }

   @ApiResponses(
      {
            @ApiResponse(responseCode = "200", description = "The API key was already locked."),
            @ApiResponse(responseCode = "201", description = "The API key has been locked."),
            @ApiResponse(
               responseCode = "404",
               description = "The API key does not exist.",
               content = {
                     @Content(mediaType = "application/vnd.api+json", schema = @Schema(ref = "json-api.yaml#/components/schemas/ErrorDocumentResponse")),
                     @Content(mediaType = "application/json", schema = @Schema(ref = "json-api.yaml#/components/schemas/ErrorDocumentResponse"))
               }
            )
      }
   )
   @POST
   @Operation(
      description = "Locks the specified API key.\n<div class=\"iam-resource-return\">response</div>",
      tags = "Technical Clients",
      summary = "Lock API key"
   )
   @Produces({"application/vnd.api+json", "application/json;qs=0.9"})
   public Response lockClient(@Parameter(description = "The identification of the API key.") @PathParam("apiKeyId") String apiKeyId) {
      Optional<ApiKey> apiKey = ((ApiKeyService)this.apiKeyService.get()).findApiKey(DefaultStringIdentity.identity(apiKeyId, ApiKey.class));
      if (apiKey.isEmpty()) {
         return ErrorResponse.notFound().build().toResponse();
      }

      ApiKey apiKeyToLock = apiKey.get();
      if (apiKeyToLock.isLocked()) {
         return Response.ok().build();
      }

      apiKeyToLock.setLocked(true);
      ((ApiKeyService)this.apiKeyService.get()).updateApiKey(apiKeyToLock);
      return Response.status(Status.CREATED).build();
   }

   @ApiResponses(
      {
            @ApiResponse(responseCode = "200", description = "The API key was already unlocked."),
            @ApiResponse(responseCode = "204", description = "The API key has been unlocked."),
            @ApiResponse(
               responseCode = "404",
               description = "The API key does not exist.",
               content = {
                     @Content(mediaType = "application/vnd.api+json", schema = @Schema(ref = "json-api.yaml#/components/schemas/ErrorDocumentResponse")),
                     @Content(mediaType = "application/json", schema = @Schema(ref = "json-api.yaml#/components/schemas/ErrorDocumentResponse"))
               }
            )
      }
   )
   @DELETE
   @Operation(
      description = "Unlocks the specified API key.\n<div class=\"iam-resource-return\">response</div>",
      tags = "Technical Clients",
      summary = "Unlock API key"
   )
   @Produces({"application/vnd.api+json", "application/json;qs=0.9"})
   public Response unlockClient(@Parameter(description = "The identification of the API key.") @PathParam("apiKeyId") String apiKeyId) {
      Optional<ApiKey> apiKey = ((ApiKeyService)this.apiKeyService.get()).findApiKey(DefaultStringIdentity.identity(apiKeyId, ApiKey.class));
      if (apiKey.isEmpty()) {
         return ErrorResponse.notFound().build().toResponse();
      }

      ApiKey apiKeyToUnlock = apiKey.get();
      if (!apiKeyToUnlock.isLocked()) {
         return Response.ok().build();
      }

      apiKeyToUnlock.setLocked(false);
      ((ApiKeyService)this.apiKeyService.get()).updateApiKey(apiKeyToUnlock);
      return Response.noContent().build();
   }
}
