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

import com.airlock.iam.authentication.infrastructure.generated.transfer.response.TermsOfServiceAuthResultDataCollectionDocument;
import com.airlock.iam.authentication.infrastructure.transfer.response.TermsOfServiceAuthResultData;
import com.airlock.iam.flow.auth.api.infrastructure.generated.transfer.response.AuthenticationFlowResultDataResourceDocument;
import com.airlock.iam.flow.shared.infrastructure.resource.TermsOfServiceResourceImpl;
import io.swagger.v3.oas.annotations.Operation;
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.Consumes;
import jakarta.ws.rs.POST;
import jakarta.ws.rs.Path;
import jakarta.ws.rs.Produces;
import jakarta.ws.rs.core.Response;

@Path("/terms-of-services")
public class AuthenticationTermsOfServiceFlowResource {
   private final Provider<TermsOfServiceResourceImpl> resourceImpl;

   @Inject
   public AuthenticationTermsOfServiceFlowResource(Provider<TermsOfServiceResourceImpl> resourceImpl) {
      this.resourceImpl = resourceImpl;
   }

   @ApiResponse(
      responseCode = "200",
      description = "A list of terms of services has been returned.",
      content = {
            @Content(mediaType = "application/vnd.api+json", schema = @Schema(implementation = TermsOfServiceAuthResultDataCollectionDocument.class)),
            @Content(mediaType = "application/json", schema = @Schema(implementation = TermsOfServiceAuthResultDataCollectionDocument.class))
      }
   )
   @Operation(
      description = "Returns a list of terms of services that need to be accepted.\nThe language of the text is chosen by the specified Accept-Language request header. If a text is configured for the given language,\nthe text will contain the message in the desired language. Otherwise, the text will contain the message in the\nconfigured default language.\n<div class=\"iam-resource-return\">A list of terms of services</div>",
      tags = "Terms of Services",
      summary = "Get terms"
   )
   @Path("retrieve")
   @POST
   @Consumes("application/json")
   @Produces({"application/vnd.api+json", "application/json;qs=0.9"})
   public Response retrieveOpenTermsOfService() {
      return ((TermsOfServiceResourceImpl)this.resourceImpl.get()).retrieveOpenTermsOfService(TermsOfServiceAuthResultData.class);
   }

   @ApiResponse(
      responseCode = "204",
      description = "Denial of the terms of services has been registered and the current authentication flow has been successfully aborted."
   )
   @Operation(
      description = "Denies any of the previously retrieved terms of service.\nThis operation aborts the current flow.",
      tags = "Terms of Services",
      summary = "Deny terms"
   )
   @Path("deny-retrieved")
   @POST
   @Consumes("application/json")
   public Response deny() {
      return ((TermsOfServiceResourceImpl)this.resourceImpl.get()).denyToS();
   }

   @ApiResponses(
      {
            @ApiResponse(
               responseCode = "200",
               description = "All open terms of services that were previously retrieved have been successfully marked as accepted.",
               content = {
                     @Content(mediaType = "application/vnd.api+json", schema = @Schema(implementation = AuthenticationFlowResultDataResourceDocument.class)),
                     @Content(mediaType = "application/json", schema = @Schema(implementation = AuthenticationFlowResultDataResourceDocument.class))
               }
            ),
            @ApiResponse(
               responseCode = "403",
               description = "Called accept-retrieved before retrieve. The current authentication flow has been aborted.",
               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"))
               }
            )
      }
   )
   @Operation(
      description = "Accepts all previously retrieved terms of services.\n<div class=\"iam-resource-return\">Whether the terms of services have been successfully marked as accepted. If the attribute <tt>nextAuthStep</tt>\n is present in the response, further steps are required to successfully authenticate. If the attribute is missing,\n the user is successfully authenticated.</div>",
      tags = "Terms of Services",
      summary = "Accept terms"
   )
   @Path("accept-retrieved")
   @POST
   @Consumes("application/json")
   @Produces({"application/vnd.api+json", "application/json;qs=0.9"})
   public Response acceptRetrieved() {
      return ((TermsOfServiceResourceImpl)this.resourceImpl.get()).acceptRetrieved();
   }
}
