/*
 * 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.lenya.cms.ac.usecase.impl;

import java.io.File;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.avalon.framework.activity.Disposable;
import org.apache.avalon.framework.configuration.Configuration;
import org.apache.avalon.framework.configuration.DefaultConfigurationBuilder;
import org.apache.avalon.framework.logger.AbstractLogEnabled;
import org.apache.avalon.framework.parameters.ParameterException;
import org.apache.avalon.framework.parameters.Parameterizable;
import org.apache.avalon.framework.parameters.Parameters;
import org.apache.avalon.framework.service.ServiceException;
import org.apache.avalon.framework.service.ServiceManager;
import org.apache.avalon.framework.service.Serviceable;
import org.apache.cocoon.environment.Request;
import org.apache.lenya.ac.AccessControlException;
import org.apache.lenya.ac.Role;
import org.apache.lenya.ac.cache.BuildException;
import org.apache.lenya.ac.cache.CachingException;
import org.apache.lenya.ac.cache.SourceCache;
import org.apache.lenya.cms.ac.PolicyUtil;
import org.apache.lenya.cms.ac.usecase.UsecaseAuthorizer;
import org.apache.lenya.cms.publication.Publication;
import org.apache.lenya.cms.publication.PublicationException;
import org.apache.lenya.cms.publication.PublicationUtil;

/**
 * Authorizer for usecases.
 * <p>
 * Supported parameters via {@link Parameterizable}:
 * </p>
 * <ul>
 * <li> {@link #PARAMETER_CONFIGURATION} - location of the usecase policies file
 * (parameterizable for testing purposes) </li>
 * </ul>
 * @version $Id: UsecaseAuthorizer.java 392449 2006-04-07 23:20:38Z michi $
 */
public class UsecaseAuthorizerImpl extends AbstractLogEnabled implements UsecaseAuthorizer,
        Serviceable, Disposable, Parameterizable {

    /**
     * The name of the pseudo-usecase that governs access to pages.
     */
    public static final String VISIT_USECASE = "ac.visit";

    protected static final String PARAMETER_CONFIGURATION = "configuration";
    protected static final String TYPE = "usecase";
    protected static final String USECASE_PARAMETER = "lenya.usecase";
    private static final String AC_CONFIGURATION_FILE = "config/access-control/access-control.xml"
            .replace('/', File.separatorChar);

    private SourceCache cache;
    /**
     * the configuration URI for this component
     */
    private String configurationUri;
    private ServiceManager manager;

    /**
     * Maps publication IDs to their configuration URIs. This is a persistent
     * map to avoid unnecessary publication lookups. Whenever an authorization
     * request for a new publication is dealt with, the publication's
     * configuration URI is stored, to be re-used on later occasions (for the
     * lifetime of the component).
     */
    private Map pubId2configUri = new HashMap();

    /**
     * @see org.apache.lenya.cms.ac.usecase.UsecaseAuthorizer#authorizeUsecase(java.lang.String,
     *      org.apache.lenya.ac.Role[],
     *      org.apache.lenya.cms.publication.Publication)
     */
    public boolean authorizeUsecase(String usecase, Role[] roles, Publication publication)
            throws AccessControlException {
        return authorizeUsecase(usecase, roles, getConfigurationURI(publication));
    }

    private boolean authorizeUsecase(String usecase, Role[] roles, String _configurationUri)
            throws AccessControlException {
        getLogger().debug("Authorizing usecase [" + usecase + "]");
        boolean authorized = false;

        UsecaseRoles usecaseRoles = getUsecaseRoles(_configurationUri);

        if (usecaseRoles == null) {
            throw new AccessControlException("Usecase policies configuration not found at ["
                    + _configurationUri + "]");
        }

        if (usecaseRoles.hasRoles(usecase)) {
            getLogger().debug("Roles for usecase found.");

            List usecaseRoleIds = Arrays.asList(usecaseRoles.getRoles(usecase));

            int i = 0;
            while (!authorized && i < roles.length) {
                authorized = usecaseRoleIds.contains(roles[i].getId());
                getLogger()
                        .debug(
                                "Authorization for role [" + roles[i].getId() + "] is ["
                                        + authorized + "]");
                i++;
            }
        } else {
            getLogger().debug("No roles for usecase [" + usecase + "] found. Denying access.");
        }
        return authorized;
    }

    /**
     * @see org.apache.lenya.cms.ac.usecase.UsecaseAuthorizer#isPermitted(java.lang.String,
     *      org.apache.lenya.cms.publication.Publication,
     *      org.apache.lenya.ac.Role)
     */
    public boolean isPermitted(String usecase, Publication publication, Role role)
            throws AccessControlException {
        String configUri = getConfigurationURI(publication);
        UsecaseRoles usecaseRoles = getUsecaseRoles(configUri);
        String[] roles = usecaseRoles.getRoles(usecase);
        return Arrays.asList(roles).contains(role.getId());
    }

    /**
     * @see org.apache.lenya.cms.ac.usecase.UsecaseAuthorizer#setPermission(java.lang.String,
     *      org.apache.lenya.cms.publication.Publication,
     *      org.apache.lenya.ac.Role, boolean)
     */
    public void setPermission(String usecase, Publication publication, Role role, boolean granted)
            throws AccessControlException {
        String configUri = getConfigurationURI(publication);
        if (configUri.startsWith("aggregate-")) {
            configUri = configUri.substring("aggregate-".length());
        }
        UsecaseRoles usecaseRoles = getUsecaseRoles(configUri);
        List roles = Arrays.asList(usecaseRoles.getRoles(usecase));
        String roleId = role.getId();
        if (granted) {
            if (!roles.contains(roleId)) {
                usecaseRoles.addRole(usecase, roleId);
            }
        } else {
            if (roles.contains(roleId)) {
                usecaseRoles.removeRole(usecase, roleId);
            }
        }
        UsecaseRolesBuilder builder = new UsecaseRolesBuilder();
        try {
            builder.save(usecaseRoles, configUri, this.manager);
        } catch (BuildException e) {
            throw new AccessControlException(e);
        }
    }

    /**
     * This method will substitute VISIT_USECASE if no USECASE_PARAMETER is set,
     * so that it can be used to authorize plain page access as well.
     * @see org.apache.lenya.ac.Authorizer#authorize(org.apache.cocoon.environment.Request)
     */
    public boolean authorize(Request request) throws AccessControlException {

        String usecase = request.getParameter(USECASE_PARAMETER);
        if (usecase == null || "".equals(usecase)) {
            usecase = VISIT_USECASE;
        }

        boolean authorized = false;

        try {
            String _configurationUri;
            // Check if the service has been parameterized with a
            // configuration URI. This can be used for testing purposes etc.
            if (getConfigurationURI() != null) {
                _configurationUri = getConfigurationURI();
            } else {
                Publication publication = PublicationUtil.getPublication(this.manager, request);
                _configurationUri = getConfigurationURI(publication);
            }

            Role[] roles = PolicyUtil.getRoles(request);
            authorized = authorizeUsecase(usecase, roles, _configurationUri);
        } catch (final PublicationException e) {
            throw new AccessControlException(e);
        } catch (final AccessControlException e) {
            throw new AccessControlException(e);
        }

        return authorized;
    }

    /**
     * Returns the configuration source cache.
     * @return A source cache.
     */
    private SourceCache getCache() {
        return this.cache;
    }

    /**
     * Returns the source URI of the usecase role configuration file for a
     * certain publication.
     * 
     * @param publication The publication.
     * @return A string representing a URI.
     */
    protected String getConfigurationURI(Publication publication) {

        String configURI = (String) this.pubId2configUri.get(publication.getId());
        if (configURI == null) {
            try {
                Configuration config = getConfiguration(publication);
                Configuration[] authorizerConfigs = config.getChildren("authorizer");
                for (int i = 0; i < authorizerConfigs.length; i++) {
                    if (authorizerConfigs[i].getAttribute("type").equals("usecase")) {
                        Configuration paraConfig = authorizerConfigs[i].getChild("parameter");
                        configURI = paraConfig.getAttribute("value");
                        this.pubId2configUri.put(publication.getId(), configURI);
                    }
                }
            } catch (Exception e) {
                getLogger().error(e.getMessage(), e);
            }
        }
        return configURI;
    }

    protected UsecaseRoles getUsecaseRoles(String _configurationUri) throws AccessControlException {
        UsecaseRolesBuilder builder = new UsecaseRolesBuilder();
        UsecaseRoles usecaseRoles;
        try {
            usecaseRoles = (UsecaseRoles) getCache().get(_configurationUri, builder);
        } catch (CachingException e) {
            throw new AccessControlException(e);
        }
        return usecaseRoles;
    }

    /**
     * @see org.apache.avalon.framework.service.Serviceable#service(org.apache.avalon.framework.service.ServiceManager)
     */
    public void service(ServiceManager _manager) throws ServiceException {
        getLogger().debug("Servicing [" + getClass().getName() + "]");
        this.manager = _manager;
        this.cache = (SourceCache) _manager.lookup(SourceCache.ROLE);
    }

    /**
     * @see org.apache.avalon.framework.activity.Disposable#dispose()
     */
    public void dispose() {
        if (getCache() != null) {
            this.manager.release(getCache());
        }
    }

    public void parameterize(Parameters parameters) throws ParameterException {
        if (parameters.isParameter(PARAMETER_CONFIGURATION)) {
            this.configurationUri = parameters.getParameter(PARAMETER_CONFIGURATION);
        }
    }

    private String getConfigurationURI() {
        return this.configurationUri;
    }

    /**
     * Retrieves access control configuration of a specific publication.
     * @param publication The publication.
     * @return Configuration
     * @throws AccessControlException when something went wrong.
     */
    private Configuration getConfiguration(Publication publication) throws AccessControlException {
        File configurationFile = new File(publication.getDirectory(), AC_CONFIGURATION_FILE);

        if (configurationFile.isFile()) {
            try {
                Configuration configuration = new DefaultConfigurationBuilder()
                        .buildFromFile(configurationFile);
                return configuration;
            } catch (Exception e) {
                throw new AccessControlException(e);
            }
        } else {
            throw new AccessControlException("No such file or directory: " + configurationFile);
        }
    }

}
