/*
 * 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.jsecurity.web.config;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.jsecurity.config.ConfigurationException;
import org.jsecurity.config.IniConfiguration;
import org.jsecurity.config.ReflectionBuilder;
import org.jsecurity.mgt.RealmSecurityManager;
import org.jsecurity.util.AntPathMatcher;
import org.jsecurity.util.PatternMatcher;
import static org.jsecurity.util.StringUtils.split;
import org.jsecurity.web.DefaultWebSecurityManager;
import org.jsecurity.web.WebUtils;
import org.jsecurity.web.filter.PathConfigProcessor;
import org.jsecurity.web.filter.authc.AnonymousFilter;
import org.jsecurity.web.filter.authc.BasicHttpAuthenticationFilter;
import org.jsecurity.web.filter.authc.FormAuthenticationFilter;
import org.jsecurity.web.filter.authc.UserFilter;
import org.jsecurity.web.filter.authz.PermissionsAuthorizationFilter;
import org.jsecurity.web.filter.authz.RolesAuthorizationFilter;
import org.jsecurity.web.servlet.AdviceFilter;
import org.jsecurity.web.servlet.FilterChainWrapper;

import javax.servlet.*;
import java.util.*;

/**
 * TODO - Class JavaDoc
 *
 * @author Les Hazlewood
 * @since Jun 1, 2008 11:02:44 PM
 */
public class IniWebConfiguration extends IniConfiguration implements WebConfiguration {

    private static final Log log = LogFactory.getLog(IniWebConfiguration.class);

    public static final String FILTERS = "filters";
    public static final String URLS = "urls";

    protected FilterConfig filterConfig;

    protected Map<String, List<Filter>> chains;

    protected PatternMatcher pathMatcher = new AntPathMatcher();

    public IniWebConfiguration() {
        chains = new LinkedHashMap<String, List<Filter>>();
    }

    public FilterConfig getFilterConfig() {
        return filterConfig;
    }

    public void setFilterConfig(FilterConfig filterConfig) {
        this.filterConfig = filterConfig;
    }

    public FilterChain getChain(ServletRequest request, ServletResponse response, FilterChain originalChain) {
        if (this.chains == null || this.chains.isEmpty()) {
            return null;
        }

        String requestURI = getPathWithinApplication(request);

        for (String path : this.chains.keySet()) {

            // If the path does match, then pass on to the subclass implementation for specific checks:
            if (pathMatches(path, requestURI)) {
                if (log.isTraceEnabled()) {
                    log.trace("Matched path [" + path + "] for requestURI [" + requestURI + "].  " +
                            "Utilizing corresponding filter chain...");
                }
                List<Filter> pathFilters = this.chains.get(path);
                if (pathFilters != null && !pathFilters.isEmpty()) {
                    return new FilterChainWrapper(originalChain, pathFilters);
                }
            }
        }

        return null;
    }

    /**
     * Returns <code>true</code> if the <code>path</code> matches the specified <code>pattern</code> string,
     * <code>false</code> otherwise.
     * <p/>
     * Simply delegates to
     * <b><code>this.pathMatcher.{@link org.jsecurity.util.PatternMatcher#matches(String, String) matches(pattern,path)}</code></b>,
     * but can be overridden by subclasses for custom matching behavior.
     *
     * @param pattern the pattern to match against
     * @param path    the value to match with the specified <code>pattern</code>
     * @return <code>true</code> if the <code>path</code> matches the specified <code>pattern</code> string,
     *         <code>false</code> otherwise.
     */
    protected boolean pathMatches(String pattern, String path) {
        return pathMatcher.matches(pattern, path);
    }

    protected String getPathWithinApplication(ServletRequest request) {
        return WebUtils.getPathWithinApplication(WebUtils.toHttp(request));
    }

    protected RealmSecurityManager newSecurityManagerInstance() {
        return new DefaultWebSecurityManager();
    }

    /**
     * 1.  First builds the filter instances.
     * 2.  Applys url mappings to these filters
     * 3.  Creates a collection of Filter chains (list of Filter objects) that will be used by the JSecurityFilter.
     *
     * @param sections
     */
    protected void afterSecurityManagerSet(Map<String, Map<String, String>> sections) {
        //filters section:
        Map<String, String> section = sections.get(FILTERS);
        Map<String, Filter> filters = getFilters(section);

        //urls section:
        section = sections.get(URLS);
        this.chains = createChains(section, filters);

        initFilters(this.chains);
    }

    protected void initFilters(Map<String, List<Filter>> chains) {
        if (chains == null || chains.isEmpty()) {
            return;
        }

        //add 'em to a set so we only initialize each one once:
        Set<Filter> filters = new LinkedHashSet<Filter>();
        for (List<Filter> pathFilters : chains.values()) {
            filters.addAll(pathFilters);
        }

        //now initialize each one:
        for (Filter filter : filters) {
            initFilter(filter);
        }
    }

    /**
     * Initializes the filter by calling <code>filter.init( {@link #getFilterConfig() getFilterConfig()} );</code>.
     *
     * @param filter the filter to initialize with the <code>FilterConfig</code>.
     */
    protected void initFilter(Filter filter) {
        try {
            filter.init(getFilterConfig());
        } catch (ServletException e) {
            throw new ConfigurationException(e);
        }
    }

    @SuppressWarnings({"unchecked"})
    protected Map<String, Filter> getFilters(Map<String, String> section) {

        Map<String, Filter> filters = createDefaultFilters();

        if (section != null && !section.isEmpty()) {
            ReflectionBuilder builder = new ReflectionBuilder(filters);
            Map built = builder.buildObjects(section);
            assertFilters(built);
            filters = (Map<String, Filter>) built;
        }

        return filters;
    }

    protected void assertFilters(Map<String, ?> map) {
        if (map == null || map.isEmpty()) {
            return;
        }
        for (Map.Entry<String, ?> entry : map.entrySet()) {
            String key = entry.getKey();
            Object value = entry.getValue();
            assertFilter(key, value);
        }
    }

    protected void assertFilter(String name, Object o) throws ConfigurationException {
        if (!(o instanceof Filter)) {
            String msg = "[" + FILTERS + "] section specified a filter named '" + name + "', which does not " +
                    "implement the " + Filter.class.getName() + " interface.  Only Filter implementations may be " +
                    "defined.";
            throw new ConfigurationException(msg);
        }
    }

    protected Map<String, Filter> createDefaultFilters() {
        Map<String, Filter> filters = new LinkedHashMap<String, Filter>();

        String name = "anon";
        AdviceFilter filter = new AnonymousFilter();
        filter.setName(name);
        filters.put(name, filter);

        name = "user";
        filter = new UserFilter();
        filter.setName(name);
        filters.put(name, filter);

        name = "authc";
        filter = new FormAuthenticationFilter();
        filter.setName(name);
        filters.put(name, filter);

        name = "authcBasic";
        filter = new BasicHttpAuthenticationFilter();
        filter.setName(name);
        filters.put(name, filter);

        name = "roles";
        filter = new RolesAuthorizationFilter();
        filter.setName(name);
        filters.put(name, filter);

        name = "perms";
        filter = new PermissionsAuthorizationFilter();
        filter.setName(name);
        filters.put(name, filter);

        return filters;
    }

    public Map<String, List<Filter>> createChains(Map<String, String> urls, Map<String, Filter> filters) {
        if (urls == null || urls.isEmpty()) {
            if (log.isDebugEnabled()) {
                log.debug("No urls to process.");
            }
            return null;
        }
        if (filters == null || filters.isEmpty()) {
            if (log.isDebugEnabled()) {
                log.debug("No filters to process.");
            }
            return null;
        }

        if (log.isTraceEnabled()) {
            log.trace("Before url processing.");
        }

        Map<String, List<Filter>> pathChains = new LinkedHashMap<String, List<Filter>>(urls.size());

        for (Map.Entry<String, String> entry : urls.entrySet()) {
            String path = entry.getKey();
            String value = entry.getValue();

            if (log.isDebugEnabled()) {
                log.debug("Processing path [" + path + "] with value [" + value + "]");
            }

            List<Filter> pathFilters = new ArrayList<Filter>();

            //parse the value by tokenizing it to get the resulting filter-specific config entries
            //
            //e.g. for a value of
            //
            //     "authc, roles[admin,user], perms[file:edit]"
            //
            // the resulting token array would equal
            //
            //     { "authc", "roles[admin,user]", "perms[file:edit]" }
            //
            String[] filterTokens = split(value, ',', '[', ']', true, true);

            //each token is specific to each filter.
            //strip the name and extract any filter-specific config between brackets [ ]
            for (String token : filterTokens) {
                String[] nameAndConfig = token.split("\\[", 2);
                String name = nameAndConfig[0];
                String config = null;

                if (nameAndConfig.length == 2) {
                    config = nameAndConfig[1];
                    //if there was an open bracket, there was a close bracket, so strip it too:
                    config = config.substring(0, config.length() - 1);
                }

                //now we have the filter name, path and (possibly null) path-specific config.  Let's apply them:
                Filter filter = filters.get(name);
                if (filter == null) {
                    String msg = "Path [" + path + "] specified a filter named '" + name + "', but that " +
                            "filter has not been specified in the [" + FILTERS + "] section.";
                    throw new ConfigurationException(msg);
                }
                if (filter instanceof PathConfigProcessor) {
                    if (log.isDebugEnabled()) {
                        log.debug("Applying path [" + path + "] to filter [" + name + "] " +
                                "with config [" + config + "]");
                    }
                    ((PathConfigProcessor) filter).processPathConfig(path, config);
                }

                pathFilters.add(filter);
            }

            if (!pathFilters.isEmpty()) {
                pathChains.put(path, pathFilters);
            }
        }

        if (pathChains.isEmpty()) {
            return null;
        }

        return pathChains;
    }
}
