package cz.muni.ics.oidc.web;

import cz.muni.ics.oidc.server.configurations.PerunOidcConfig;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.filter.OncePerRequestFilter;

import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.Collections;
import java.util.Enumeration;
import java.util.List;
import java.util.stream.Collectors;

@Slf4j
public class LogRequestFilter extends OncePerRequestFilter {

    public static final String SEPARATOR = "---------------------------------------------------------------------\n";
    public static final String WRAPPER = "#####################################################################\n";

    public static final String MSG = WRAPPER +
            "Incoming request: {} {}\n" +
            SEPARATOR +
            "PARAMETERS: {}\n" +
            SEPARATOR +
            "HEADERS: {}\n" +
            WRAPPER;

    private final boolean enabled;

    public LogRequestFilter(PerunOidcConfig config) {
        enabled = config.isLogRequestsEnabled();
    }

    @Override
    protected void doFilterInternal(final HttpServletRequest req,
                                    HttpServletResponse response,
                                    FilterChain filterChain)
            throws ServletException, IOException
    {
        if (enabled) {
            log.trace(MSG, req.getMethod(), req.getRequestURL(),
                    Collections.list(req.getParameterNames())
                            .stream()
                            .collect(
                                    Collectors.toMap(
                                            parameter -> parameter,
                                            parameter -> List.of(req.getParameterValues((String) parameter))
                                    )
                            ),
                    Collections.list(req.getHeaderNames())
                            .stream()
                            .collect(
                                    Collectors.toMap(
                                            header -> header,
                                            header -> Collections.list(req.getHeaders((String) header))
                                                    .stream()
                                                    .collect(Collectors.toList())
                                    )
                            )
            );
        }

        filterChain.doFilter(req, response);
    }

}
