package ru.yandex.qe.bus.servlet;

import java.io.IOException;
import java.util.regex.Pattern;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.annotation.WebFilter;

import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.slf4j.MDC;

import ru.yandex.qe.logging.turbo.MDCLogThresholdFilter;

@WebFilter(
        filterName = "bus-log-threshold-filter",
        urlPatterns = "/api/*",
        asyncSupported = true
)
public class LogThresholdFilter implements Filter {

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

    private static final String THRESHOLD_PARAM = "_log_threshold";
    private static final String PATTERN_PARAM = "_log_pattern";

    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
    }

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
        String threshold = request.getParameter(THRESHOLD_PARAM);
        String pattern = request.getParameter(PATTERN_PARAM);
        boolean enable = StringUtils.isNoneBlank(threshold);
        if (enable) {
            LOG.info("Set log threshold {} for request", threshold);
            MDC.put(MDCLogThresholdFilter.MDC_THRESHOLD_KEY, threshold);
            if (pattern != null && !pattern.isEmpty()) {
                try {
                    MDC.put(MDCLogThresholdFilter.MDC_PATTERN_KEY, Pattern.compile(pattern).pattern());
                } catch (Exception e) {
                    LOG.error("Invalid pattern for log threshold - {}: {}", threshold, pattern);
                    pattern = null;
                }
            }
        }
        try {
            chain.doFilter(request, response);
        } finally {
            if (enable) {
                MDC.remove(MDCLogThresholdFilter.MDC_THRESHOLD_KEY);
                if (pattern != null && !pattern.isEmpty()) {
                    MDC.remove(MDCLogThresholdFilter.MDC_PATTERN_KEY);
                }
            }
        }
    }

    @Override
    public void destroy() {
    }
}
