package com.airlock.iam.common.infrastructure;

import jakarta.servlet.ServletRequest;
import jakarta.servlet.http.HttpServletRequest;
import java.nio.file.Paths;
import java.util.Collection;
import java.util.List;
import java.util.Optional;
import java.util.regex.Pattern;

public final class RequestPathUtil {
   private static final Pattern UI_APP_PATTERN = Pattern.compile("/ui/app(/.*)?");
   private static final Collection<String> STATIC_ASSET_PATHS = List.of("/css/", "/images/", "/js/", "/fonts/");

   private RequestPathUtil() {
   }

   public static boolean isRestApiCall(ServletRequest request) {
      return iamServletPath(request).map(servletPath -> servletPath.startsWith("/rest/")).orElse(false);
   }

   public static boolean isRestApiCall(String contextPath, String requestUri) {
      return Paths.get(requestUri).startsWith(Paths.get(contextPath, "rest"));
   }

   public static boolean isJerseyCall(ServletRequest request) {
      return isRestApiCall(request)
         || iamServletPath(request).map(servletPath -> servletPath.equals("/oauth2/v3") || servletPath.equals("/saml2")).orElse(false);
   }

   public static boolean isSpaCall(ServletRequest request) {
      return iamServletPath(request).map(servletPath -> servletPath.startsWith("/ui/")).orElse(false);
   }

   public static boolean isStaticAsset(ServletRequest request) {
      Optional<String> servletPath = iamServletPath(request);
      return servletPath.isEmpty()
         ? false
         : isRootFaviconPath(servletPath.get()) || hasStaticAssetPrefix(servletPath.get()) || isStaticSpaAsset(request, servletPath.get());
   }

   public static boolean isMsofbaCall(ServletRequest request) {
      return iamServletPath(request).map(path -> path.startsWith("/public/msofba/")).orElse(false);
   }

   private static Optional<String> iamServletPath(ServletRequest request) {
      return !(request instanceof HttpServletRequest) ? Optional.empty() : Optional.of(((HttpServletRequest)request).getServletPath());
   }

   private static boolean isStaticSpaAsset(ServletRequest request, String servletPath) {
      return isSpaCall(request) && !UI_APP_PATTERN.matcher(servletPath).matches();
   }

   private static boolean hasStaticAssetPrefix(String path) {
      return STATIC_ASSET_PATHS.stream().anyMatch(path::startsWith);
   }

   private static boolean isRootFaviconPath(String servletPath) {
      return "/favicon.ico".equals(servletPath);
   }
}
