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

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import javax.xml.XMLConstants;
import javax.xml.namespace.QName;
import javax.xml.stream.XMLStreamException;
import javax.xml.stream.XMLStreamWriter;

import org.apache.neethi.util.PolicyIntersector;

/**
 * Policy is a PolicyOperator that requires to satisfy all of its
 * PolicyComponents. It is always the outermost component of a Policy.
 * 
 */
public class Policy extends All {

    private Map<QName, String> attributes = new HashMap<QName, String>();
    private String namespace;
    private PolicyRegistry registry;
    
    public Policy() {
    }
    public Policy(PolicyRegistry r) {
        registry = r;
    }
    public Policy(PolicyRegistry r, String ns) {
        this(r);
        namespace = ns;
    }
    public Policy(PolicyOperator parent) {
        super(parent);
    }

    public PolicyRegistry getPolicyRegistry() {
        return registry;
    }
    public void setPolicyRegistry(PolicyRegistry reg) {
        registry = reg;
    }
    
    public String getNamespace() {
        return namespace;
    }

    /**
     * Returns a Normalized version of self. If {@code deep} is set
     * {@code false} then the assertions are not normalized and it returns a
     * partially normalized version of self.
     * 
     * @param deep
     *            a flag to indicate whether to normalize the assertions
     * @return a Policy that is normalized version of self
     */
    public Policy normalize(boolean deep) {
        return normalize(registry, deep);
    }

    /**
     * Returns a normalized version of self.If {@code deep} is set
     * {@code false} then the assertions are not normalized and it returns a
     * partially normalized version of self.
     * 
     * @param reg
     *            a PolicyRegistry from which the PolicyReferences are resolved
     * @param deep
     *            a flag to indicate whether to normalize the assertions
     * @return a normalized version of self
     */
    public Policy normalize(PolicyRegistry reg, boolean deep) {
        return normalize(this, reg, deep);
    }

    /**
     * Returns a Policy that is the merge of specified Policy and self.
     * 
     * @param policy
     *            the Policy to be merged with self
     * @return a Policy that is the merge of the specified Policy and self
     */
    public Policy merge(Policy policy) {

        Policy result = new Policy(registry, namespace);
        result.addPolicyComponents(getPolicyComponents());
        result.addPolicyComponents(policy.getPolicyComponents());
        return result;
    }

    public Policy intersect(Policy policy) {
        return intersect(policy, true);
    }
    public Policy intersect(Policy policy, boolean strict) {
        return new PolicyIntersector(strict).intersect(normalize(true), policy.normalize(true), true);
    }

    /**
     * Serializes the Policy to a XMLStreamWriter.
     */
    public void serialize(XMLStreamWriter writer) throws XMLStreamException {
        String nspace = namespace;
        if (namespace == null) {
            nspace = Constants.findPolicyNamespace(writer);
        }
        String wspPrefix = writer.getPrefix(nspace);

        if (wspPrefix == null) {
            wspPrefix = Constants.ATTR_WSP;
            writer.setPrefix(wspPrefix, nspace);
        }

        String wsuPrefix = writer.getPrefix(Constants.URI_WSU_NS);
        if (wsuPrefix == null) {
            wsuPrefix = Constants.ATTR_WSU;
            writer.setPrefix(wsuPrefix, Constants.URI_WSU_NS);
        }

        writer.writeStartElement(wspPrefix, Constants.ELEM_POLICY,
                nspace);

        QName key;
        
        String prefix = null;
        String namespaceURI = null;
        String localName = null;

        Map<String, String> prefix2ns = new HashMap<String, String>();
        boolean writeNS = true;

        for (Map.Entry<QName, String> ents : attributes.entrySet()) {
            
            key = ents.getKey();
            localName = key.getLocalPart();
            
            namespaceURI = key.getNamespaceURI();
            namespaceURI = (namespaceURI == null || namespaceURI.length() == 0) ? null : namespaceURI;
                        
            if (namespaceURI != null && XMLConstants.XMLNS_ATTRIBUTE_NS_URI.equals(namespaceURI)) {
                writer.writeNamespace(localName, ents.getValue());
                if (nspace.equals(ents.getValue())) {
                    writeNS = false;
                }
            } else if (namespaceURI != null) {
                String writerPrefix = writer.getPrefix(namespaceURI);
                writerPrefix = (writerPrefix == null || writerPrefix.length() == 0) ? null : writerPrefix;
                
                if (writerPrefix == null) {
                    prefix = key.getPrefix();
                    prefix = (prefix == null || prefix.length() == 0) ? null : prefix;
                    
                } else {
                    prefix = writerPrefix;
                }
                
                if (prefix != null) {
                    writer.writeAttribute(prefix, namespaceURI, localName, ents.getValue());
                    prefix2ns.put(prefix, key.getNamespaceURI());

                } else {
                    writer.writeAttribute(namespaceURI, localName, ents.getValue());
                }
                    
            } else {
                writer.writeAttribute(localName, getAttribute(key));
            }

            
        }

        if (writeNS) {
            // writes xmlns:wsp=".."
            writer.writeNamespace(wspPrefix, nspace);
        }


        for (String pfx :prefix2ns.keySet()) {
            writer.writeNamespace(pfx, prefix2ns.get(pfx));
        }

        for (PolicyComponent policyComponent : getPolicyComponents()) {
            policyComponent.serialize(writer);
        }

        writer.writeEndElement();

    }

    /**
     * Returns Constants.TYPE_POLICY
     */
    public short getType() {
        return Constants.TYPE_POLICY;
    }

    /**
     * Returns an Iterator that will return a list of assertions correspond to a
     * Policy alternative if any. The {@code iterator.next()} will return a
     * list of assertions correspond to a Policy alternative if any and
     * {@code iterator.hasNext()} will indicates whether there is another
     * Policy alternative.
     * 
     * @return An iterator over the list of alternatives
     */
    public Iterator<List<Assertion>> getAlternatives() {
        return new PolicyIterator(this, registry);
    }
    public Iterator<List<Assertion>> getAlternatives(PolicyRegistry reg) {
        return new PolicyIterator(this, reg);
    }

    private class PolicyIterator implements Iterator<List<Assertion>> {
        Iterator<PolicyComponent> alternatives;

        public PolicyIterator(Policy policy, PolicyRegistry reg) {
            policy = policy.normalize(reg, false);
            ExactlyOne exactlyOne = (ExactlyOne) policy
                    .getFirstPolicyComponent();
            alternatives = exactlyOne.getPolicyComponents().iterator();
        }

        public boolean hasNext() {
            return alternatives.hasNext();
        }

        public List<Assertion> next() {
            List<PolicyComponent> pcs = ((All) alternatives.next()).getPolicyComponents();
            List<Assertion> asserts = new ArrayList<Assertion>(pcs.size());
            for (PolicyComponent pc : pcs) {
                if (pc instanceof Assertion) {
                    asserts.add((Assertion)pc);
                }
            }
            return asserts;
        }

        public void remove() {
            throw new UnsupportedOperationException(
                    "policyAlternative.remove() is not supported");
        }
    }

    /**
     * Adds an attribute to self.
     * 
     * @param name
     *            the name of the attribute
     * @param value
     *            the value of the attribute
     */
    public void addAttribute(QName name, String value) {
        attributes.put(name, value);
    }

    /**
     * Returns the value of the attribute specified by the QName. Returns
     * {@code null} if not present.
     * 
     * @param name
     *            the QName of the attribute
     * @return the value of the attribute specified by the QName
     */
    public String getAttribute(QName name) {
        return attributes.get(name);
    }

    /**
     * Returns a {@link Map} of all attributes of self.
     * 
     * @return a Map of all attributes of self
     */
    public Map<QName, String> getAttributes() {
        return attributes;
    }

    /**
     * Sets the {@code Name} attribute of self.
     * 
     * @param name
     *            the Name attribute of self
     */
    public void setName(String name) {
        addAttribute(new QName("", Constants.ATTR_NAME), name);
    }

    /**
     * Returns the {@code Name} attribute of self.
     * 
     * @return the Name attribute of self
     */
    public String getName() {
        return getAttribute(new QName("", Constants.ATTR_NAME));
    }

    /**
     * Sets the wsu:Id attribute of self.
     * 
     * @param id
     *            the Id attribute of self
     */
    public void setId(String id) {
        addAttribute(new QName(Constants.URI_WSU_NS, Constants.ATTR_ID), id);
    }

    /**
     * Returns the Id attribute of self.
     * 
     * @return the Id attribute of self
     */
    public String getId() {
        return getAttribute(new QName(Constants.URI_WSU_NS, Constants.ATTR_ID));
    }
}
