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

import java.io.InputStream;

import javax.xml.parsers.ParserConfigurationException;

import org.apache.lenya.ac.AccessControlException;
import org.apache.lenya.ac.AccessController;
import org.apache.lenya.ac.Accreditable;
import org.apache.lenya.ac.AccreditableManager;
import org.apache.lenya.ac.Credential;
import org.apache.lenya.ac.ModifiablePolicy;
import org.apache.lenya.ac.Policy;
import org.apache.lenya.ac.Role;
import org.apache.lenya.ac.User;
import org.apache.lenya.ac.World;
import org.apache.lenya.ac.cache.BuildException;
import org.apache.lenya.ac.cache.InputStreamBuilder;
import org.apache.lenya.xml.DocumentHelper;
import org.apache.lenya.xml.NamespaceHelper;
import org.w3c.dom.Document;
import org.w3c.dom.Element;

/**
 * Builds policies from input streams.
 * @version $Id$
 */
public class PolicyBuilder implements InputStreamBuilder {

    /**
     * Ctor.
     * @param _accreditableManager An accreditable manager.
     */
    public PolicyBuilder(AccreditableManager _accreditableManager) {
        assert _accreditableManager != null;
        this.accreditableManager = _accreditableManager;
    }
    
    /**
     * Returns the accreditable manager.
     * @return An accreditable manager.
     */
    public AccreditableManager getAccreditableManager() {
        return this.accreditableManager;
    }

    private AccreditableManager accreditableManager;

    protected static final String POLICY_ELEMENT = "policy";
    protected static final String GROUP_ELEMENT = "group";
    protected static final String USER_ELEMENT = "user";
    protected static final String ROLE_ELEMENT = "role";
    protected static final String WORLD_ELEMENT = "world";
    protected static final String IP_RANGE_ELEMENT = "ip-range";
    protected static final String ID_ATTRIBUTE = "id";
    protected static final String SSL_ATTRIBUTE = "ssl";
    protected static final String METHOD_ATTRIBUTE = "method";
    
    /**
     * Builds a policy from an input stream.
     * @param stream The input stream to read the policy from.
     * @return A policy.
     * @throws AccessControlException when something went wrong.
     */
    public ModifiablePolicy buildPolicy(InputStream stream)
        throws AccessControlException {

        Document document;

        try {
            document = DocumentHelper.readDocument(stream);
        } catch (Exception e) {
            throw new AccessControlException(e);
        }

        return buildPolicy(document);
    }

    /**
     * Builds a policy from an XML document.
     * @param document The XML document.
     * @return A policy.
     * @throws AccessControlException when something went wrong.
     */
    public ModifiablePolicy buildPolicy(Document document)
        throws AccessControlException {

        DefaultPolicy policy = new DefaultPolicy();
        Element policyElement = document.getDocumentElement();
        assert policyElement.getLocalName().equals(POLICY_ELEMENT);

        NamespaceHelper helper =
            new NamespaceHelper(
                AccessController.NAMESPACE,
                AccessController.DEFAULT_PREFIX,
                document);

        Element[] credentialElements = helper.getChildren(policyElement);

        for (int i = 0; i < credentialElements.length; i++) {
            Accreditable accreditable = null;

            String id = credentialElements[i].getAttribute(ID_ATTRIBUTE);
            accreditable = getAccreditable(credentialElements[i].getLocalName(), id);

            Element[] roleElements = helper.getChildren(credentialElements[i], ROLE_ELEMENT);

            for (int j = 0; j < roleElements.length; j++) {
                String roleId = roleElements[j].getAttribute(ID_ATTRIBUTE);
                Role role = getAccreditableManager().getRoleManager().getRole(roleId);
                CredentialImpl credential = new CredentialImpl(accreditable, role);
                String method = roleElements[j].getAttribute(METHOD_ATTRIBUTE);
                // If method is not set, we assume DENY 
                if (method.length() == 0) method = CredentialImpl.DENY;
                credential.setMethod(method);
                policy.addCredential(credential);
            }

        }
        
        boolean ssl = false;
        String sslString = policyElement.getAttribute(SSL_ATTRIBUTE);
        if (sslString != null) {
            ssl = Boolean.valueOf(sslString).booleanValue();
        }
        policy.setSSL(ssl);

        return policy;
    }

    /**
     * Creates an accredtiable for an element.
     * @param elementName The elment name.
     * @param id The ID of the accreditable.
     * @return An accreditable.
     * @throws AccessControlException when something went wrong.
     */
    protected Accreditable getAccreditable(
        String elementName,
        String id)
        throws AccessControlException {
        Accreditable accreditable = null;

        if (elementName.equals(USER_ELEMENT)) {
            accreditable = getAccreditableManager().getUserManager().getUser(id);
        } else if (elementName.equals(GROUP_ELEMENT)) {
            accreditable = getAccreditableManager().getGroupManager().getGroup(id);
        } else if (elementName.equals(WORLD_ELEMENT)) {
            accreditable = World.getInstance();
        } else if (elementName.equals(IP_RANGE_ELEMENT)) {
            accreditable = getAccreditableManager().getIPRangeManager().getIPRange(id);
        }

        if (accreditable == null) {
            throw new AccessControlException(
                "Unknown accreditable [" + elementName + "] with ID [" + id + "]");
        }

        return accreditable;
    }

    /**
     * Saves a policy to an XML document.
     * @param policy The policy to save.
     * @return A DOM document.
     * @throws AccessControlException when something went wrong.
     */
    public static Document savePolicy(Policy policy) throws AccessControlException {
        NamespaceHelper helper;

        try {
            helper =
                new NamespaceHelper(
                    AccessController.NAMESPACE,
                    AccessController.DEFAULT_PREFIX,
                    POLICY_ELEMENT);
        } catch (ParserConfigurationException e) {
            throw new AccessControlException(e);
        }

        Credential[] credentials = ((DefaultPolicy) policy).getCredentials();
        Element policyElement = helper.getDocument().getDocumentElement();

        for (int i = 0; i < credentials.length; i++) {
            Accreditable accreditable = credentials[i].getAccreditable();
            Element accreditableElement = save(accreditable, helper);
            
            Role role = credentials[i].getRole();
            Element roleElement = helper.createElement(ROLE_ELEMENT);
            roleElement.setAttribute(ID_ATTRIBUTE, role.getId());
            roleElement.setAttribute(METHOD_ATTRIBUTE, credentials[i].getMethod());
            accreditableElement.appendChild(roleElement);
            
            policyElement.appendChild(accreditableElement);
        }
        
        policyElement.setAttribute(SSL_ATTRIBUTE, Boolean.toString(policy.isSSLProtected()));

        return helper.getDocument();
    }

    /**
     * Saves an accreditable to an XML element.
     * @param accreditable The accreditable.
     * @param helper The namespace helper to be used.
     * @return An XML element.
     * @throws AccessControlException when something went wrong.
     */
    protected static Element save(Accreditable accreditable, NamespaceHelper helper)
        throws AccessControlException {
        String localName = null;
        String id = null;

        if (accreditable instanceof User) {
            localName = USER_ELEMENT;
            id = ((User) accreditable).getId();
        } else if (accreditable instanceof AbstractGroup) {
            localName = GROUP_ELEMENT;
            id = ((AbstractGroup) accreditable).getId();
        } else if (accreditable instanceof World) {
            localName = WORLD_ELEMENT;
        } else if (accreditable instanceof AbstractIPRange) {
            localName = IP_RANGE_ELEMENT;
            id = ((AbstractIPRange) accreditable).getId();
        }

        if (localName == null) {
            throw new AccessControlException("Could not save accreditable [" + accreditable + "]");
        }

        Element element = helper.createElement(localName);

        if (id != null) {
            element.setAttribute(ID_ATTRIBUTE, id);
        }

        return element;
    }

    /**
     * @see org.apache.lenya.ac.cache.InputStreamBuilder#build(java.io.InputStream)
     */
    public Object build(InputStream stream) throws BuildException {
        Object value = null;
        try {
            value = buildPolicy(stream);
        } catch (AccessControlException e) {
            throw new BuildException(e);
        }
        return value;
    }

}
