package com.github.digital_wonderland.sling_metrics.filter;

import com.codahale.metrics.MetricRegistry;
import com.codahale.metrics.Timer;
import com.github.digital_wonderland.sling_metrics.service.MetricService;
import org.apache.felix.scr.annotations.Activate;
import org.apache.felix.scr.annotations.Property;
import org.apache.felix.scr.annotations.Reference;
import org.apache.felix.scr.annotations.sling.SlingFilter;
import org.apache.felix.scr.annotations.sling.SlingFilterScope;
import org.apache.sling.api.SlingHttpServletRequest;
import org.osgi.service.component.ComponentContext;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.servlet.*;
import java.io.IOException;

@SlingFilter(scope = SlingFilterScope.COMPONENT,
        order = -10000,
        metatype = true,
        name = "Metrics Component Filter",
        description = "Sling Components Filter which generates Metrics for Components")
public class ComponentFilter implements javax.servlet.Filter {

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

    @Property(label = "Enabled", boolValue = true, description = "Should the filter be enabled")
    private static final String COMPONENT_FILTER_ENABLED = "componentFilter.enabled";

    @Reference
    protected MetricService metricService;

    private boolean isEnabled = false;

    @Activate
    protected void activate(final ComponentContext context) {
        isEnabled = (Boolean) context.getProperties().get(COMPONENT_FILTER_ENABLED);
        LOG.info("ComponentFilter.isEnabled: [{}]", isEnabled);
    }

    @Override
    public void init(final FilterConfig filterConfig) throws ServletException {
        LOG.info("ComponentFilter init()");
    }

    @Override
    public void doFilter(final ServletRequest servletRequest, final ServletResponse servletResponse, final FilterChain filterChain) throws IOException, ServletException {
        LOG.debug("ComponentFilter doFilter()");

        if(isEnabled && metricService.isEnabled()) {
            if(servletRequest instanceof SlingHttpServletRequest) {
                final SlingHttpServletRequest slingRequest = (SlingHttpServletRequest) servletRequest;
                final String resourceType = slingRequest.getResource().getResourceType();
                final MetricRegistry registry = metricService.getRegistry();
                final Timer.Context context = registry.timer(normalizeResourceType(resourceType)).time();
                try {
                    filterChain.doFilter(servletRequest, servletResponse);
                } finally {
                    context.stop();
                }
            } else {
                LOG.error("Metrics ComponentFilter got called for non SlingHttpServletRequest");
            }
        }
    }

    private String normalizeResourceType(final String resourceType) {
        return ("components." + resourceType).replaceAll("[\\./:]+", ".");
    }

    @Override
    public void destroy() {
        LOG.info("ComponentFilter destroy()");
    }
}

@@ -1525,36 +1525,37 @@
 D);%0A        LOG.
-info
+debug
 (%22ComponentFilte
@@ -1597,153 +1597,8 @@
  %7D%0A%0A
-    @Override%0A    public void init(final FilterConfig filterConfig) throws ServletException %7B%0A        LOG.info(%22ComponentFilter init()%22);%0A    %7D%0A%0A
     
@@ -2807,103 +2807,7 @@
    %7D
-%0A%0A    @Override%0A    public void destroy() %7B%0A        LOG.info(%22ComponentFilter destroy()%22);%0A    %7D
 %0A%7D%0A

clean up