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

import ch.ergon.restal.jsonapi.document.data.ResourceDocument;
import com.airlock.iam.authentication.application.settings.OpenIdConnectSessionManagementSettings;
import com.airlock.iam.authentication.infrastructure.generated.transfer.response.ui.OpenIdConnectSessionManagementUiConfigDataResourceDocument;
import com.airlock.iam.authentication.infrastructure.service.ui.OAuth2UiService;
import com.airlock.iam.authentication.infrastructure.transfer.response.ui.OpenIdConnectSessionManagementUiConfigData;
import com.airlock.iam.base.infrastructure.error.ErrorResponse;
import com.airlock.iam.base.infrastructure.mapper.entity.RestMapper;
import com.airlock.iam.common.api.infrastructure.annotation.RequiresWritableSession;
import com.airlock.iam.common.application.jsonapi.ResourceIdentifierUtils;
import com.airlock.iam.elog.api.ELogger;
import com.airlock.iam.elog.api.ELoggerFactory;
import com.airlock.iam.oauth2.api.domain.model.AuthorizationServerId;
import com.airlock.iam.oauth2.infrastructure.validation.AuthorizationServerIdValidator;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.extensions.Extension;
import io.swagger.v3.oas.annotations.extensions.ExtensionProperty;
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.GET;
import jakarta.ws.rs.Path;
import jakarta.ws.rs.PathParam;
import jakarta.ws.rs.Produces;
import jakarta.ws.rs.core.Response;
import java.util.Optional;

@Path("/ui/configuration/oauth2/")
public class OAuth2UiConfigurationResource {
   private static final ELogger LOG = ELoggerFactory.getLogger(OAuth2UiConfigurationResource.class);
   private final Provider<OAuth2UiService> service;
   private final RestMapper mapper;
   private final Provider<AuthorizationServerIdValidator> authorizationServerIdValidator;

   @Inject
   public OAuth2UiConfigurationResource(
      Provider<OAuth2UiService> service, RestMapper mapper, Provider<AuthorizationServerIdValidator> authorizationServerIdValidator
   ) {
      this.service = service;
      this.mapper = mapper;
      this.authorizationServerIdValidator = authorizationServerIdValidator;
   }

   @ApiResponses(
      {
            @ApiResponse(
               responseCode = "200",
               description = "The response contains the default application ID.",
               content = {
                     @Content(
                        mediaType = "application/vnd.api+json",
                        schema = @Schema(implementation = OpenIdConnectSessionManagementUiConfigDataResourceDocument.class)
                     ),
                     @Content(
                        mediaType = "application/json",
                        schema = @Schema(implementation = OpenIdConnectSessionManagementUiConfigDataResourceDocument.class)
                     )
               }
            ),
            @ApiResponse(
               responseCode = "404",
               description = "If no UI is available.",
               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 = "Returns the configuration for the OpenID Connect session management 1.0 UI.\n<div class=\"iam-resource-return\">A JSON containing the configuration for the authorization server</div>",
      extensions = @Extension(properties = @ExtensionProperty(name = "x-internal", value = "true")),
      tags = "UI",
      summary = "Get configuration"
   )
   @GET
   @Path("authorization-servers/{authorizationServerId}/session-management")
   @Produces({"application/vnd.api+json", "application/json;qs=0.9"})
   @RequiresWritableSession
   public Response getCheckSessionConfiguration(
      @Parameter(description = "The authorization server ID.") @PathParam("authorizationServerId") String authorizationServerId
   ) {
      ((AuthorizationServerIdValidator)this.authorizationServerIdValidator.get()).validateAuthorizationServer(authorizationServerId);
      Optional<OpenIdConnectSessionManagementSettings> openIdConnectCheckSessionUiSettings = ((OAuth2UiService)this.service.get())
         .getOpenIdConnectCheckSessionUiSettings(AuthorizationServerId.authorizationServerId(authorizationServerId));
      if (openIdConnectCheckSessionUiSettings.isEmpty()) {
         LOG.debug("OpenID Connect Session Management configuration not found.");
         return ErrorResponse.notFound().build().toResponse();
      } else {
         ResourceDocument<OpenIdConnectSessionManagementUiConfigData> document = this.mapper
            .forElement(openIdConnectCheckSessionUiSettings.get(), OpenIdConnectSessionManagementUiConfigData.class)
            .withIdSupplier(ResourceIdentifierUtils::getIdFor)
            .toResourceDocument();
         return Response.ok(document).build();
      }
   }
}
