/*
 * 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.engine.impl.parameters;

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.http.HttpServletRequest;

import java.io.File;
import java.io.IOException;

import org.apache.sling.api.SlingHttpServletRequest;
import org.apache.sling.settings.SlingSettingsService;
import org.osgi.service.component.annotations.Activate;
import org.osgi.service.component.annotations.Component;
import org.osgi.service.component.annotations.Reference;
import org.osgi.service.component.propertytypes.ServiceDescription;
import org.osgi.service.component.propertytypes.ServiceRanking;
import org.osgi.service.component.propertytypes.ServiceVendor;
import org.osgi.service.http.whiteboard.propertytypes.HttpWhiteboardContextSelect;
import org.osgi.service.http.whiteboard.propertytypes.HttpWhiteboardFilterPattern;
import org.osgi.service.metatype.annotations.AttributeDefinition;
import org.osgi.service.metatype.annotations.Designate;
import org.osgi.service.metatype.annotations.ObjectClassDefinition;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

@Component(name = RequestParameterSupportConfigurer.PID, service = Filter.class)
@HttpWhiteboardContextSelect("(osgi.http.whiteboard.context.name=org.apache.sling)")
@HttpWhiteboardFilterPattern("/")
@ServiceDescription("Filter for request parameter support")
@ServiceVendor("The Apache Software Foundation")
@ServiceRanking(Integer.MAX_VALUE)
@Designate(ocd = RequestParameterSupportConfigurer.Config.class)
public class RequestParameterSupportConfigurer implements Filter {

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

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
            throws IOException, ServletException {
        if (request instanceof HttpServletRequest
                && !(request instanceof ParameterSupportHttpServletRequestWrapper)
                && !(request instanceof SlingHttpServletRequest)) {
            chain.doFilter(ParameterSupport.getParameterSupportRequestWrapper((HttpServletRequest) request), response);
        } else {
            chain.doFilter(request, response);
        }
    }

    @Override
    public void destroy() {}

    @ObjectClassDefinition(
            name = "Apache Sling Request Parameter Handling",
            description = "Configures Sling's request parameter handling.")
    public @interface Config {
        @AttributeDefinition(
                name = "Default Parameter Encoding",
                description = "The default request parameter encoding used to decode request "
                        + "parameters into strings. If this property is not set the default encoding "
                        + "is 'ISO-8859-1' as mandated by the Servlet API spec. This default encoding "
                        + "is used if the '_charset_' request parameter is not set to another "
                        + "(supported) character encoding. Applications being sure to always use the "
                        + "same encoding (e.g. UTF-8) can set this default here and may omit the "
                        + "'_charset_' request parameter")
        String sling_default_parameter_encoding() default Util.ENCODING_DIRECT;

        @AttributeDefinition(
                name = "Maximum POST Parameters",
                description = "The maximum number of parameters supported. To prevent a DOS-style attack with an "
                        + "overrunning number of parameters the number of parameters supported can be limited. This "
                        + "includes all of the query string as well as application/x-www-form-urlencoded and "
                        + "multipart/form-data parameters. The default value is " + ParameterMap.DEFAULT_MAX_PARAMS
                        + ".")
        int sling_default_max_parameters() default ParameterMap.DEFAULT_MAX_PARAMS;

        @AttributeDefinition(
                name = "Temporary File Location",
                description = "The temporary directory where uploaded files are written to disk. The default is "
                        + "null, which means the directory given by the 'java.io.tmpdir' system property.")
        String file_location();

        @AttributeDefinition(
                name = "File Save Threshold",
                description = "The size threshold after which the file will be written to disk. The default is 256KB.")
        int file_threshold() default 256000;

        @AttributeDefinition(
                name = "Maximum File Size",
                description = "The maximum size allowed for uploaded files. The default is -1, which means unlimited.")
        long file_max() default -1;

        @AttributeDefinition(
                name = "Maximum Request Size",
                description =
                        "The maximum size allowed for multipart/form-data requests. The default is -1, which means unlimited.")
        long request_max() default -1;

        @AttributeDefinition(
                name = "Check Additional Parameters",
                description =
                        "Enable this if you want to include request parameters added through the container, e.g through a valve.")
        boolean sling_default_parameter_checkForAdditionalContainerParameters() default false;

        @AttributeDefinition(
                name = "Maximum File Count",
                description =
                        "The maximum number of files allowed for multipart/form-data requests in a single request. The default is 50.")
        long request_max_file_count() default 50;
    }

    static final String PID = "org.apache.sling.engine.parameters";

    /** default log */
    private final Logger log = LoggerFactory.getLogger(PID);

    @Reference
    private SlingSettingsService settignsService;

    @Activate
    private void configure(final Config config) {
        final String fixEncoding = config.sling_default_parameter_encoding();
        final int maxParams = config.sling_default_max_parameters();
        final long maxRequestSize = config.request_max();
        final String fileLocation = getFileLocation(config.file_location());
        final long maxFileSize = config.file_max();
        final int fileSizeThreshold = config.file_threshold();
        final boolean checkAddParameters = config.sling_default_parameter_checkForAdditionalContainerParameters();

        if (log.isInfoEnabled()) {
            log.info("Default Character Encoding: {}", fixEncoding);
            log.info("Parameter Number Limit: {}", (maxParams < 0) ? "unlimited" : maxParams);
            log.info("Maximum Request Size: {}", (maxParams < 0) ? "unlimited" : maxRequestSize);
            log.info("Temporary File Location: {}", fileLocation);
            log.info("Maximum File Size: {}", maxFileSize);
            log.info("Tempory File Creation Threshold: {}", fileSizeThreshold);
            log.info("Check for additional container parameters: {}", checkAddParameters);
            log.info("Maximum File Count: {}", config.request_max_file_count());
        }

        Util.setDefaultFixEncoding(fixEncoding);
        ParameterMap.setMaxParameters(maxParams);
        ParameterSupport.configure(
                maxRequestSize,
                fileLocation,
                maxFileSize,
                fileSizeThreshold,
                checkAddParameters,
                config.request_max_file_count());
    }

    private String getFileLocation(String fileLocation) {
        if (fileLocation != null) {
            File file = new File(fileLocation);
            if (!file.isAbsolute()) {
                file = new File(this.settignsService.getSlingHomePath(), fileLocation);
                fileLocation = file.getAbsolutePath();
            }
            if (file.exists()) {
                if (!file.isDirectory()) {
                    log.error(
                            "Configured temporary file location {} exists but is not a directory; using java.io.tmpdir instead",
                            fileLocation);
                    fileLocation = null;
                }
            } else {
                if (!file.mkdirs()) {
                    log.error("Cannot create temporary file directory {}; using java.io.tmpdir instead", fileLocation);
                    fileLocation = null;
                }
            }
        }
        return fileLocation;
    }
}
