package fr.titionfire.ffsaf;

import io.vertx.core.http.HttpServerRequest;
import jakarta.annotation.Priority;
import jakarta.ws.rs.Priorities;
import jakarta.ws.rs.container.ContainerRequestContext;
import jakarta.ws.rs.container.ContainerResponseContext;
import jakarta.ws.rs.container.ContainerResponseFilter;
import jakarta.ws.rs.container.ResourceInfo;
import jakarta.ws.rs.core.Context;
import jakarta.ws.rs.core.MediaType;
import jakarta.ws.rs.core.UriInfo;
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 FrontendForwardingFilter implements ContainerResponseFilter {

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

    @Context
    UriInfo info;

    @Context
    HttpServerRequest request;

    @Context
    ResourceInfo resourceInfo;

    private static String text = null;

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

    @Override
    public void filter(ContainerRequestContext requestContext, ContainerResponseContext responseContext) {

        final String method = requestContext.getMethod();
        final String path = info.getPath();
        final String address = request.remoteAddress().toString();

        if (!path.equals("/api")) {
            LOG.infof("Request %s %s from IP %s", method, path, address);
        }

        int status = responseContext.getStatus();
        if (status != 404 && !(status == 405 && "GET".equals(requestContext.getMethod()))) {
            return;
        }

        boolean isApiNamespace = path.matches(API_NAMESPACE_REGEX);
        if (isApiNamespace) {
            return;
        }
        boolean isFilename = path.matches(FILENAME_REGEX);
        if (isFilename) {
            return;
        }
        boolean actualErrorResponse = resourceInfo != null && resourceInfo.getResourceMethod() != null;
        if (actualErrorResponse) {
            return;
        }

        LOG.info("redirect");

        if (text == null)
            text = new Scanner(Objects.requireNonNull(this.getClass().getResourceAsStream("/META-INF/resources/index.html")),
                    StandardCharsets.UTF_8).useDelimiter("\\A").next();
        responseContext.setStatus(200);
        responseContext.setEntity(text, null, MediaType.TEXT_HTML_TYPE);
    }
}
