package fr.titionfire.ffsaf;

import io.vertx.core.http.HttpServerRequest;
import jakarta.annotation.Priority;
import jakarta.ws.rs.NotFoundException;
import jakarta.ws.rs.Priorities;
import jakarta.ws.rs.container.ResourceInfo;
import jakarta.ws.rs.core.Context;
import jakarta.ws.rs.core.MediaType;
import jakarta.ws.rs.core.Response;
import jakarta.ws.rs.core.UriInfo;
import jakarta.ws.rs.ext.ExceptionMapper;
import jakarta.ws.rs.ext.Provider;
import org.jboss.logging.Logger;

import java.nio.charset.StandardCharsets;
import java.util.Objects;
import java.util.Scanner;

@Provider
@Priority(Priorities.USER)
public class FrontendForwardingFilterREST implements ExceptionMapper<NotFoundException> {

    private static final Logger LOG = Logger.getLogger(FrontendForwardingFilterREST.class);

    @Context
    UriInfo info;

    @Context
    HttpServerRequest request;

    @Context
    ResourceInfo resourceInfo;

    private static String text = null;

    private static final String API_NAMESPACE_REGEX = "^/(api/.*|api|openapi|q/.*)";
    private static final String FILENAME_REGEX = "^/.*\\.[^.]+$";

    @Override
    public Response toResponse(NotFoundException exception) {
        final String path = info.getPath();
        final String address = request.remoteAddress().toString();

        boolean isApiNamespace = path.matches(API_NAMESPACE_REGEX);
        if (isApiNamespace) {
            LOG.infof("Request %s from IP %s => %d", "method", path, address, exception.getResponse().getStatus());
            return exception.getResponse();
        }
        boolean isFilename = path.matches(FILENAME_REGEX);
        if (isFilename) {
            LOG.infof("Request %s from IP %s => %d", "method", path, address, exception.getResponse().getStatus());
            return exception.getResponse();
        }
        boolean actualErrorResponse = resourceInfo != null && resourceInfo.getResourceMethod() != null;
        if (actualErrorResponse) {
            LOG.infof("Request %s from IP %s => %d", "method", path, address, exception.getResponse().getStatus());
            return exception.getResponse();
        }

        if (text == null)
            text = new Scanner(
                    Objects.requireNonNull(this.getClass().getResourceAsStream("/META-INF/resources/index.html")),
                    StandardCharsets.UTF_8).useDelimiter("\\A").next();
        LOG.infof("Request %s from IP %s => redirect", "method", path, address);
        return Response.status(200).entity(text).type(MediaType.TEXT_HTML_TYPE).build();
    }
}
