/*
 * 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.felix.http.sslfilter.internal;

import static org.apache.felix.http.sslfilter.internal.SslFilterConstants.HDR_X_FORWARDED_SSL;
import static org.apache.felix.http.sslfilter.internal.SslFilterConstants.HDR_X_FORWARDED_SSL_CERTIFICATE;

import java.io.IOException;
import java.security.cert.CertificateException;
import java.util.Dictionary;

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 javax.servlet.http.HttpServletResponse;

import org.osgi.service.cm.ConfigurationException;
import org.osgi.service.http.whiteboard.Preprocessor;
import org.osgi.service.log.LogService;

@SuppressWarnings("rawtypes")
public class SslFilter implements  Preprocessor
{
    public static final String PID = "org.apache.felix.http.sslfilter.SslFilter";

    private static final String DEFAULT_SSL_HEADER = HDR_X_FORWARDED_SSL;
    private static final String DEFAULT_SSL_VALUE = "on";
    private static final String DEFAULT_CERT_HEADER = HDR_X_FORWARDED_SSL_CERTIFICATE;
    private static final boolean DEFAULT_REWRITE_ABSOLUTE_URLS = false;

    private static final String PROP_SSL_HEADER = "ssl-forward.header";
    private static final String PROP_SSL_VALUE = "ssl-forward.value";
    private static final String PROP_SSL_CERT_KEY = "ssl-forward-cert.header";
    private static final String PROP_REWRITE_ABSOLUTE_URLS = "rewrite.absolute.urls";

    private volatile ConfigHolder config;

    SslFilter()
    {
        this.config = new ConfigHolder(DEFAULT_SSL_HEADER,
                DEFAULT_SSL_VALUE,
                DEFAULT_CERT_HEADER,
                DEFAULT_REWRITE_ABSOLUTE_URLS);
    }

    @Override
    public void destroy()
    {
        // No explicit destroy needed...
    }

    @Override
    public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException
    {
        final ConfigHolder cfg = this.config;

        HttpServletRequest httpReq = (HttpServletRequest) req;
        HttpServletResponse httpResp = (HttpServletResponse) res;

        if (cfg.sslValue.equalsIgnoreCase(httpReq.getHeader(cfg.sslHeader)))
        {
            try
            {
                httpResp = new SslFilterResponse(httpResp, httpReq, cfg);
                // In case this fails, we fall back to the original HTTP request, which is better than nothing...
                httpReq = new SslFilterRequest(httpReq, httpReq.getHeader(cfg.certHeader));
            }
            catch (CertificateException e)
            {
                SystemLogger.log(LogService.LOG_WARNING, "Failed to create SSL filter request! Problem parsing client certificates?! Client certificate will *not* be forwarded...", e);
            }
        }

        // forward the request making sure any certificate is removed again after the request processing gets back here
        try
        {
            chain.doFilter(httpReq, httpResp);
        }
        finally
        {
            if (httpReq instanceof SslFilterRequest)
            {
                ((SslFilterRequest) httpReq).done();
            }
        }
    }

    @Override
    public void init(FilterConfig config)
    {
        // make sure there is some configuration
    }

    void configure(Dictionary properties) throws ConfigurationException
    {
        String certHeader = DEFAULT_CERT_HEADER;
        String sslHeader = DEFAULT_SSL_HEADER;
        String sslValue = DEFAULT_SSL_VALUE;
        boolean rewriteUrls = DEFAULT_REWRITE_ABSOLUTE_URLS;

        if (properties != null)
        {
            certHeader = getOptionalString(properties, PROP_SSL_CERT_KEY);
            sslHeader = getMandatoryString(properties, PROP_SSL_HEADER);
            sslValue = getMandatoryString(properties, PROP_SSL_VALUE);
            rewriteUrls = getOptionalBoolean(properties, PROP_REWRITE_ABSOLUTE_URLS, rewriteUrls);
        }

        this.config = new ConfigHolder(sslHeader, sslValue, certHeader, rewriteUrls);

        SystemLogger.log(LogService.LOG_INFO, "SSL filter (re)configured with: " + "SSL forward header = '" + sslHeader + "'; SSL forward value = '" + sslValue + "'; SSL certificate header = '"
            + certHeader + "'.");
    }

    private boolean getOptionalBoolean(Dictionary properties,
            String key,
            boolean defaultValue) throws ConfigurationException
    {
        Object raw = properties.get(key);
        if (raw == null)
        {
            return defaultValue;
        }
        if ( raw instanceof Boolean )
        {
            return (Boolean)raw;
        }
        if (!(raw instanceof String))
        {
            throw new ConfigurationException(key, "invalid value");
        }
        return Boolean.valueOf((String)raw);
    }

    private String getOptionalString(Dictionary properties, String key) throws ConfigurationException
    {
        Object raw = properties.get(key);
        if (raw == null || "".equals(((String) raw).trim()))
        {
            return null;
        }
        if (!(raw instanceof String))
        {
            throw new ConfigurationException(key, "invalid value");
        }
        return ((String) raw).trim();
    }

    private String getMandatoryString(Dictionary properties, String key) throws ConfigurationException
    {
        String value = getOptionalString(properties, key);
        if (value == null)
        {
            throw new ConfigurationException(key, "missing value");
        }
        return value;
    }

    static class ConfigHolder
    {
        final String certHeader;
        final String sslHeader;
        final String sslValue;
        final boolean rewriteAbsoluteUrls;

        public ConfigHolder(String sslHeader, String sslValue, String certHeader,
                boolean rewriteAbsoluteUrls)
        {
            this.sslHeader = sslHeader;
            this.sslValue = sslValue;
            this.certHeader = certHeader;
            this.rewriteAbsoluteUrls = rewriteAbsoluteUrls;
        }
    }
}
