package com.gnx.telemedicine.filter;

import com.gnx.telemedicine.util.CorrelationIdUtil;
import jakarta.servlet.FilterChain;
import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import lombok.extern.slf4j.Slf4j;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;
import org.springframework.web.filter.OncePerRequestFilter;
import org.springframework.web.util.ContentCachingRequestWrapper;
import org.springframework.web.util.ContentCachingResponseWrapper;

import java.io.IOException;

/**
 * Filter to generate and propagate correlation IDs across the request lifecycle.
 * This filter should be executed early in the filter chain to ensure correlation IDs
 * are available for all subsequent processing.
 */
@Component
@Order(1) // Execute early in the filter chain
@Slf4j
public class CorrelationIdFilter extends OncePerRequestFilter {

    @Override
    protected void doFilterInternal(
            HttpServletRequest request,
            HttpServletResponse response,
            FilterChain filterChain) throws ServletException, IOException {
        
        try {
            // Get or generate correlation ID
            String correlationId = CorrelationIdUtil.getOrGenerateCorrelationId(request);
            
            // Set correlation ID in MDC and response header
            CorrelationIdUtil.setCorrelationId(correlationId, response);
            CorrelationIdUtil.setRequestPath(request.getRequestURI());
            CorrelationIdUtil.setRequestMethod(request.getMethod());
            
            // Log request start
            log.debug("Request started: {} {} | Correlation ID: {}", 
                    request.getMethod(), 
                    request.getRequestURI(), 
                    correlationId);
            
            // Continue filter chain
            filterChain.doFilter(request, response);
            
            // Log request completion
            log.debug("Request completed: {} {} | Status: {} | Correlation ID: {}", 
                    request.getMethod(), 
                    request.getRequestURI(), 
                    response.getStatus(), 
                    correlationId);
            
        } finally {
            // Always clear MDC to prevent memory leaks
            CorrelationIdUtil.clear();
        }
    }
}

