package com.atlassian.jira.web.filters;

import com.atlassian.seraph.config.SecurityConfig;
import com.atlassian.seraph.filter.SecurityFilter;

import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.security.Principal;

import org.apache.log4j.Category;

/**
 * Logs JIRA username and request URL via log4j. See http://confluence.atlassian.com/display/JIRACOM/User+access+logging
 */
public class AccessLogFilter implements Filter
{
    private FilterConfig config;
    Category log = Category.getInstance(AccessLogFilter.class);

    public void init(FilterConfig filterConfig) throws ServletException
    {
        this.config = filterConfig;
        log.info("AccessLogFilter initialized. Format is: <user> <url> <starting memory free (kb)> +- <difference in free mem (kb)> <query time (ms)>");
    }

    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain chain) throws IOException, ServletException
    {
        if (log.isInfoEnabled())
        {
            HttpServletRequest request = (HttpServletRequest) servletRequest;
            HttpServletResponse response = (HttpServletResponse) servletResponse;
            final String url = request.getRequestURL().toString();
            if (interestingURL(url))
            {
                String user = request.getRemoteUser();
                long startMem = Runtime.getRuntime().freeMemory() >> 10; // div 1024
                long t1 = System.currentTimeMillis();
                chain.doFilter(request, response);
                long t2 = System.currentTimeMillis();
                long endMem = Runtime.getRuntime().freeMemory() >> 10; // div 1024
                long memDiff = (endMem - startMem);

                StringBuffer buf = new StringBuffer();
                buf.append(user == null ? "-" : "" + user).append(" ");
                buf.append(url);
                buf.append(" ").append(startMem);
                if (memDiff > 0) buf.append("+").append(memDiff);
                if (memDiff < 0) buf.append(memDiff);
                buf.append(" ").append(t2-t1);
                log.info(buf.toString());
                return;
            }
        }
        chain.doFilter(servletRequest, servletResponse);
    }

    private boolean interestingURL(final String url)
    {
        return (url != null) &&
                !url.endsWith(".gif") &&
                !url.endsWith(".png") &&
                !url.endsWith(".jpg") &&
                !url.endsWith(".css") &&
                !url.endsWith(".ico") &&
                !url.endsWith(".js");
    }

    public void destroy()
    {
        config = null;
    }
}
