/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  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.jackrabbit.xml.nodetype;

import java.util.Iterator;
import java.util.Map;

import javax.jcr.PropertyType;
import javax.jcr.version.OnParentVersionAction;

import org.apache.jackrabbit.name.QName;
import org.apache.jackrabbit.state.nodetype.NodeDefinitionState;
import org.apache.jackrabbit.state.nodetype.NodeTypeManagerState;
import org.apache.jackrabbit.state.nodetype.NodeTypeState;
import org.apache.jackrabbit.state.nodetype.PropertyDefinitionState;
import org.apache.xerces.util.XMLChar;
import org.xml.sax.Attributes;
import org.xml.sax.ContentHandler;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.AttributesImpl;

/**
 * TODO
 */
class NodeTypeXMLWriter {

    private final NodeTypeManagerState nodeTypeManagerState;

    private Map namespaces;

    private ContentHandler handler;

    public NodeTypeXMLWriter(NodeTypeManagerState nodeTypeManagerState) {
        this.nodeTypeManagerState = nodeTypeManagerState;
    }

    private void startElement(String name) throws SAXException {
        handler.startElement("", name, name, null);
    }

    private void startElement(String name, Attributes attributes)
            throws SAXException {
        handler.startElement("", name, name, attributes);
    }

    private void endElement(String name) throws SAXException {
        handler.endElement("", name, name);
    }

    public void write(ContentHandler handler) throws SAXException {
        this.namespaces =
            NamespaceExtractor.extractNamespaces(nodeTypeManagerState);
        this.handler = handler;
        handler.startDocument();

        Iterator entries = namespaces.entrySet().iterator();
        while (entries.hasNext()) {
            Map.Entry entry = (Map.Entry) entries.next();
            handler.startPrefixMapping(
                    (String) entry.getValue(), (String) entry.getKey()); 
        }

        write(nodeTypeManagerState);

        Iterator values = namespaces.values().iterator();
        while (values.hasNext()) {
            handler.endPrefixMapping((String) values.next()); 
        }

        handler.endDocument();
    }

    private void write(NodeTypeManagerState nodeTypeManagerState)
            throws SAXException {
        startElement("nodeTypes");
        NodeTypeState[] nodeTypeStates = nodeTypeManagerState.getNodeTypeStates();
        for (int i = 0; i < nodeTypeStates.length; i++) {
            write(nodeTypeStates[i]);
        }
        endElement("nodeTypes");
    }

    private void write(NodeTypeState nodeTypeState) throws SAXException {
        AttributesImpl attributes = new AttributesImpl();
        addAttribute(attributes, "name", nodeTypeState.getName());
        QName primaryItemName = nodeTypeState.getPrimaryItemName();
        if (primaryItemName != null) {
            addAttribute(attributes, "primaryItemName", primaryItemName);
        } else {
            addAttribute(attributes, "primaryItemName", "");
        }
        addAttribute(attributes, "isMixin", nodeTypeState.isMixin());
        addAttribute(attributes, "hasOrderableChildNodes", nodeTypeState.hasOrderableChildNodes());
        startElement("nodeType", attributes);

        QName[] supertypeNames = nodeTypeState.getSupertypeNames();
        if (supertypeNames != null && supertypeNames.length > 0) {
            startElement("supertypes");
            for (int i = 0; i < supertypeNames.length; i++) {
                startElement("supertype");
                char[] characters = filterXML(toJCRName(supertypeNames[i]));
                handler.characters(characters, 0, characters.length);
                endElement("supertype");
            }
            endElement("supertypes");
        }

        PropertyDefinitionState[] propertyDefinitionStates =
            nodeTypeState.getPropertyDefinitionStates();
        for (int i = 0; i < propertyDefinitionStates.length; i++) {
            write(propertyDefinitionStates[i]);
        }

        NodeDefinitionState[] childNodeDefinitionStates =
            nodeTypeState.getChildNodeDefinitionStates();
        for (int i = 0; i < childNodeDefinitionStates.length; i++) {
            write(childNodeDefinitionStates[i]);
        }

        endElement("nodeType");
    }

    private void write(PropertyDefinitionState propertyDefinitionState)
            throws SAXException {
        AttributesImpl attributes = new AttributesImpl();
        if (propertyDefinitionState.getName() != null) {
            addAttribute(attributes, "name", propertyDefinitionState.getName());
        } else {
            addAttribute(attributes, "name", "*");
        }
        addAttribute(
                attributes, "requiredType",
                PropertyType.nameFromValue(propertyDefinitionState.getRequiredType()));
        addAttribute(attributes, "autoCreated", propertyDefinitionState.isAutoCreated());
        addAttribute(attributes, "mandatory", propertyDefinitionState.isMandatory());
        addAttribute(
                attributes, "onParentVersion",
                OnParentVersionAction.nameFromValue(propertyDefinitionState.getOnParentVersion()));
        addAttribute(attributes, "protected", propertyDefinitionState.isProtected());
        addAttribute(attributes, "multiple", propertyDefinitionState.isMultiple());
        startElement("propertyDefinition", attributes);
        // TODO: default values
        // TODO: value constraints
        endElement("propertyDefinition");
    }

    private void write(NodeDefinitionState childNodeDefinitionState)
            throws SAXException {
        AttributesImpl attributes = new AttributesImpl();
        if (childNodeDefinitionState.getName() != null) {
            addAttribute(attributes, "name", childNodeDefinitionState.getName());
        } else {
            addAttribute(attributes, "name", "*");
        }
        if (childNodeDefinitionState.getDefaultPrimaryTypeName() != null) {
            addAttribute(attributes, "defaultPrimaryType", childNodeDefinitionState.getDefaultPrimaryTypeName());
        } else {
            addAttribute(attributes, "defaultPrimaryType", "");
        }
        addAttribute(attributes, "autoCreated", childNodeDefinitionState.isAutoCreated());
        addAttribute(attributes, "mandatory", childNodeDefinitionState.isMandatory());
        addAttribute(
                attributes, "onParentVersion",
                OnParentVersionAction.nameFromValue(childNodeDefinitionState.getOnParentVersion()));
        addAttribute(attributes, "protected", childNodeDefinitionState.isProtected());
        addAttribute(attributes, "sameNameSiblings", childNodeDefinitionState.allowsSameNameSiblings());
        startElement("childNodeDefinition", attributes);

        QName[] requiredPrimaryTypeNames = childNodeDefinitionState.getRequiredPrimaryTypeNames();
        if (requiredPrimaryTypeNames != null && requiredPrimaryTypeNames.length > 0) {
            startElement("requiredPrimaryTypes");
            for (int i = 0; i < requiredPrimaryTypeNames.length; i++) {
                startElement("requiredPrimaryType");
                char[] characters = filterXML(toJCRName(requiredPrimaryTypeNames[i]));
                handler.characters(characters, 0, characters.length);
                endElement("requiredPrimaryType");
            }
            endElement("requiredPrimaryTypes");
        }

        endElement("childNodeDefinition");
    }

    private void addAttribute(AttributesImpl attributes, String name, boolean value) {
        addAttribute(attributes, name, Boolean.toString(value));
    }

    private void addAttribute(AttributesImpl attributes, String name, QName value) {
        addAttribute(attributes, name, toJCRName(value));
    }

    private void addAttribute(AttributesImpl attributes, String name, String value) {
        attributes.addAttribute(
                "", name, name, "CDATA", new String(filterXML(value)));
    }

    private String toJCRName(QName name) {
        String prefix = (String) namespaces.get(name.getNamespaceURI());
        return prefix + ":" + name.getLocalName();
    }

    private char[] filterXML(String value) {
        char[] characters = value.toCharArray();
        for (int i = 0; i < characters.length; i++) {
            if (XMLChar.isInvalid(characters[i])) {
                characters[i] = ' '; // TODO: better escape?
            }
        }
        return characters;
    }

}
