/*
 * 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.usecase.gui.impl;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.avalon.framework.configuration.Configurable;
import org.apache.avalon.framework.configuration.Configuration;
import org.apache.avalon.framework.configuration.ConfigurationException;
import org.apache.avalon.framework.context.Context;
import org.apache.avalon.framework.context.ContextException;
import org.apache.avalon.framework.context.Contextualizable;
import org.apache.avalon.framework.logger.AbstractLogEnabled;
import org.apache.avalon.framework.service.ServiceException;
import org.apache.avalon.framework.service.ServiceManager;
import org.apache.avalon.framework.service.ServiceSelector;
import org.apache.avalon.framework.service.Serviceable;
import org.apache.cocoon.components.ContextHelper;
import org.apache.cocoon.environment.Request;
import org.apache.lenya.ac.AccessControlException;
import org.apache.lenya.ac.AccessController;
import org.apache.lenya.ac.AccessControllerResolver;
import org.apache.lenya.ac.Authorizer;
import org.apache.lenya.ac.Role;
import org.apache.lenya.cms.ac.PolicyUtil;
import org.apache.lenya.cms.ac.usecase.UsecaseAuthorizer;
import org.apache.lenya.cms.cocoon.components.context.ContextUtility;
import org.apache.lenya.cms.publication.DocumentFactory;
import org.apache.lenya.cms.publication.DocumentUtil;
import org.apache.lenya.cms.publication.Publication;
import org.apache.lenya.cms.publication.PublicationUtil;
import org.apache.lenya.cms.usecase.Usecase;
import org.apache.lenya.cms.usecase.UsecaseMessage;
import org.apache.lenya.cms.usecase.UsecaseResolver;
import org.apache.lenya.cms.usecase.gui.GUIManager;
import org.apache.lenya.cms.usecase.gui.Tab;
import org.apache.lenya.util.ServletHelper;

/**
 * GUI manager implementation.
 */
public class GUIManagerImpl extends AbstractLogEnabled implements GUIManager, Configurable,
        Serviceable, Contextualizable {

    protected static final String ELEMENT_PARAMETER = "parameter";
    protected static final String ELEMENT_TAB_GROUP = "tab-group";
    protected static final String ELEMENT_TAB = "tab";
    protected static final String ATTRIBUTE_NAME = "name";
    protected static final String ATTRIBUTE_VALUE = "value";
    protected static final String ATTRIBUTE_LABEL = "label";
    protected static final String ATTRIBUTE_USECASE = "usecase";

    private Map name2group = new HashMap();

    /**
     * @see org.apache.avalon.framework.configuration.Configurable#configure(org.apache.avalon.framework.configuration.Configuration)
     */
    public void configure(Configuration config) throws ConfigurationException {
        Configuration[] tabGroupConfigs = config.getChildren(ELEMENT_TAB_GROUP);
        for (int i = 0; i < tabGroupConfigs.length; i++) {
            String groupName = tabGroupConfigs[i].getAttribute(ATTRIBUTE_NAME);
            List group = new ArrayList();
            Configuration[] tabConfigs = tabGroupConfigs[i].getChildren(ELEMENT_TAB);
            for (int j = 0; j < tabConfigs.length; j++) {
                String name = tabConfigs[j].getAttribute(ATTRIBUTE_NAME);
                String label = tabConfigs[j].getAttribute(ATTRIBUTE_LABEL);
                String usecase = tabConfigs[j].getAttribute(ATTRIBUTE_USECASE);
                TabImpl tab = new TabImpl(groupName, name, usecase, label);
                group.add(tab);

                Configuration[] paramConfigs = tabConfigs[j].getChildren(ELEMENT_PARAMETER);
                for (int p = 0; p < paramConfigs.length; p++) {
                    String paramName = paramConfigs[p].getAttribute(ATTRIBUTE_NAME);
                    String paramValue = paramConfigs[p].getAttribute(ATTRIBUTE_VALUE);
                    tab.setParameter(paramName, paramValue);
                }
            }
            name2group.put(groupName, group.toArray(new Tab[group.size()]));
        }
    }

    /**
     * @see org.apache.lenya.cms.usecase.gui.GUIManager#getActiveTabs(java.lang.String)
     */
    public Tab[] getActiveTabs(String group) {
        Tab[] tabs = getTabs(group);
        List activeTabs = new ArrayList();
        for (int i = 0; i < tabs.length; i++) {
            if (getErrorMessages(tabs[i]).length == 0) {
                activeTabs.add(tabs[i]);
            }
        }
        return (Tab[]) activeTabs.toArray(new Tab[activeTabs.size()]);
    }

    protected Tab[] getTabs(String group) {
        Tab[] tabs = (Tab[]) name2group.get(group);
        return tabs;
    }

    /**
     * @see org.apache.lenya.cms.usecase.gui.GUIManager#getTab(java.lang.String, java.lang.String)
     */
    public Tab getTab(String group, String name) {
        Tab[] tabs = getTabs(group);
        for (int i = 0; i < tabs.length; i++) {
            if (name.equals(tabs[i].getName())) {
                return tabs[i];
            }
        }
        throw new IllegalArgumentException("No tab [" + name + "] in group [" + group + "]");
    }

    /**
     * Checks if a tab's usecase can be executed.
     * @param tab The tab.
     * @return An array of error messages.
     */
    protected UsecaseMessage[] getErrorMessages(Tab tab) {

        UsecaseMessage[] messages;

        ServiceSelector selector = null;
        AccessControllerResolver acResolver = null;
        AccessController accessController = null;
        UsecaseResolver usecaseResolver = null;
        UsecaseAuthorizer authorizer = null;
        try {

            selector = (ServiceSelector) this.manager.lookup(AccessControllerResolver.ROLE
                    + "Selector");
            acResolver = (AccessControllerResolver) selector.select(AccessControllerResolver.DEFAULT_RESOLVER);
            accessController = acResolver.resolveAccessController(this.webappUrl);

            Authorizer[] authorizers = accessController.getAuthorizers();
            for (int i = 0; i < authorizers.length; i++) {
                if (authorizers[i] instanceof UsecaseAuthorizer) {
                    authorizer = (UsecaseAuthorizer) authorizers[i];
                }
            }

            usecaseResolver = (UsecaseResolver) this.manager.lookup(UsecaseResolver.ROLE);

            // filter item if usecase not allowed
            if (tab.getUsecase() != null) {
                if (getLogger().isDebugEnabled()) {
                    getLogger().debug("Found usecase [" + tab.getUsecase() + "]");
                }

                DocumentFactory factory;
                ContextUtility util = null;
                try {
                    util = (ContextUtility) this.manager.lookup(ContextUtility.ROLE);
                    Request request = util.getRequest();
                    factory = DocumentUtil.getDocumentFactory(this.manager, request);
                } finally {
                    if (util != null) {
                        this.manager.release(util);
                    }
                }

                Publication pub = PublicationUtil.getPublicationFromUrl(this.manager,
                        factory,
                        this.webappUrl);
                if (!authorizer.authorizeUsecase(tab.getUsecase(), this.roles, pub)) {
                    if (getLogger().isDebugEnabled()) {
                        getLogger().debug("Usecase not authorized");
                    }
                    messages = new UsecaseMessage[1];
                    messages[0] = new UsecaseMessage("Access denied");
                }
            }

            if (usecaseResolver.isRegistered(this.webappUrl, tab.getUsecase())) {
                Usecase usecase = null;
                try {
                    usecase = usecaseResolver.resolve(this.webappUrl, tab.getUsecase());
                    usecase.setSourceURL(this.webappUrl);
                    usecase.setName(tab.getUsecase());
                    String[] keys = tab.getParameterNames();
                    for (int i = 0; i < keys.length; i++) {
                        usecase.setParameter(keys[i], tab.getParameter(keys[i]));
                    }
                    usecase.checkPreconditions();
                    if (usecase.hasErrors()) {
                        if (getLogger().isDebugEnabled()) {
                            getLogger().debug("Usecase preconditions not complied");
                        }

                        List msgs = usecase.getErrorMessages();
                        messages = (UsecaseMessage[]) msgs.toArray(new UsecaseMessage[msgs.size()]);
                    } else {
                        messages = new UsecaseMessage[0];
                    }
                } finally {
                    if (usecase != null) {
                        usecaseResolver.release(usecase);
                    }
                }
            } else {
                messages = new UsecaseMessage[1];
                messages[0] = new UsecaseMessage("Usecase [" + tab.getUsecase()
                        + "] is not registered!", null);
            }
        } catch (final Exception e) {
            throw new RuntimeException(e);
        } finally {
            if (usecaseResolver != null) {
                this.manager.release(usecaseResolver);
            }
            if (selector != null) {
                if (acResolver != null) {
                    if (accessController != null) {
                        acResolver.release(accessController);
                    }
                    selector.release(acResolver);
                }
                this.manager.release(selector);
            }
        }

        return messages;
    }

    private ServiceManager manager;

    /**
     * @see org.apache.avalon.framework.service.Serviceable#service(org.apache.avalon.framework.service.ServiceManager)
     */
    public void service(ServiceManager manager) throws ServiceException {
        this.manager = manager;
    }

    private String webappUrl;
    private Role[] roles;

    /**
     * @see org.apache.avalon.framework.context.Contextualizable#contextualize(org.apache.avalon.framework.context.Context)
     */
    public void contextualize(Context context) throws ContextException {
        Request request = ContextHelper.getRequest(context);
        try {
            this.roles = PolicyUtil.getRoles(request);
        } catch (AccessControlException e) {
            throw new ContextException("Obtaining roles failed: ", e);
        }
        this.webappUrl = ServletHelper.getWebappURI(request);
    }

}
