/*-
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */

package org.apache.sling.dynamicinclude;

import java.io.IOException;
import java.io.PrintWriter;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.Enumeration;
import java.util.List;

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 org.apache.commons.lang3.StringEscapeUtils;
import org.apache.commons.lang3.StringUtils;
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.apache.sling.api.resource.Resource;
import org.apache.sling.api.resource.ResourceUtil;
import org.apache.sling.dynamicinclude.generator.IncludeGenerator;
import org.apache.sling.dynamicinclude.generator.IncludeGeneratorWhiteboard;
import org.apache.sling.dynamicinclude.impl.UrlBuilder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

@SlingFilter(scope = SlingFilterScope.INCLUDE, order = -500)
public class IncludeTagFilter implements Filter {

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

    private static final String COMMENT = "<!-- SDI include (path: %s, resourceType: %s) -->\n";

    @Reference
    private ConfigurationWhiteboard configurationWhiteboard;

    @Reference
    private IncludeGeneratorWhiteboard generatorWhiteboard;

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException,
            ServletException {
        final SlingHttpServletRequest slingRequest = (SlingHttpServletRequest) request;
        final String resourceType = slingRequest.getResource().getResourceType();

        final Configuration config = configurationWhiteboard.getConfiguration(slingRequest, resourceType);
        if (config == null) {
            chain.doFilter(request, response);
            return;
        }

        final IncludeGenerator generator = generatorWhiteboard.getGenerator(config.getIncludeTypeName());
        if (generator == null) {
            LOG.error("Invalid generator: " + config.getIncludeTypeName());
            chain.doFilter(request, response);
            return;
        }

        final PrintWriter writer = response.getWriter();
        final String url = getUrl(config, slingRequest);
        if (url == null) {
            chain.doFilter(request, response);
            return;
        }

        if (config.getAddComment()) {
            writer.append(String.format(COMMENT, StringEscapeUtils.escapeHtml4(url), resourceType));
        }

        // Only write the includes markup if the required, configurable request
        // header is present
        if (shouldWriteIncludes(config, slingRequest)) {
            String include = generator.getInclude(url);
            LOG.debug(include);
            writer.append(include);
        } else {
            chain.doFilter(request, response);
        }
    }

    private boolean shouldWriteIncludes(Configuration config, SlingHttpServletRequest request) {
        if (requestHasParameters(config.getIgnoreUrlParams(), request)) {
            return false;
        }
        final String requiredHeader = config.getRequiredHeader();
        return StringUtils.isBlank(requiredHeader) || containsHeader(requiredHeader, request);
    }

    private boolean requestHasParameters(List<String> ignoreUrlParams, SlingHttpServletRequest request) {
        final Enumeration<?> paramNames = request.getParameterNames();
        while (paramNames.hasMoreElements()) {
            final String paramName = (String) paramNames.nextElement();
            if (!ignoreUrlParams.contains(paramName)) {
                return true;
            }
        }
        return false;
    }

    private boolean containsHeader(String requiredHeader, SlingHttpServletRequest request) {
        final String name, expectedValue;
        if (StringUtils.contains(requiredHeader, '=')) {
            final String split[] = StringUtils.split(requiredHeader, '=');
            name = split[0];
            expectedValue = split[1];
        } else {
            name = requiredHeader;
            expectedValue = null;
        }

        final String actualValue = request.getHeader(name);
        if (actualValue == null) {
            return false;
        } else if (expectedValue == null) {
            return true;
        } else {
            return actualValue.equalsIgnoreCase(expectedValue);
        }
    }

    private String getUrl(Configuration config, SlingHttpServletRequest request) {
        String url = buildUrl(config, request);
        if (config.isRewritePath()) {
            url = removeQuestionMark(url);
            url = request.getResourceResolver().map(request, url);
        } else {
            url = encodeJcrContentPart(url);
            try {
                url = new URI(null, null, url, null).toASCIIString();
            } catch (URISyntaxException e) {
                LOG.error("Include url is in the wrong format", e);
                return null;
            }
        }

        return url;
    }

    private String buildUrl(Configuration config, SlingHttpServletRequest request) {
        final Resource resource = request.getResource();

        final boolean synthetic = ResourceUtil.isSyntheticResource(request.getResource());
        return UrlBuilder.buildUrl(config.getIncludeSelector(), resource.getResourceType(), synthetic, config, request.getRequestPathInfo());
    }

    private static String sanitize(String path) {
        return StringUtils.defaultString(path);
    }

    private static String encodeJcrContentPart(String url) {
        return url.replace("jcr:content", "_jcr_content");
    }

    private static String removeQuestionMark(String url) {
        return url.replaceAll("[?]", "");
    }

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

    @Override
    public void destroy() {
    }
}
