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

import java.io.IOException;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;

import javax.xml.namespace.QName;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;

import org.apache.axiom.locator.loader.OMMetaFactoryLoader;
import org.apache.axiom.om.OMAbstractFactory;
import org.apache.axiom.om.OMMetaFactory;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.xml.sax.SAXException;

final class ImplementationFactory {
    static final String DESCRIPTOR_RESOURCE = "META-INF/axiom.xml";
    
    private static final String NS = "http://ws.apache.org/axiom/";
    private static final QName QNAME_IMPLEMENTATIONS = new QName(NS, "implementations");
    private static final QName QNAME_IMPLEMENTATION = new QName(NS, "implementation");
    private static final QName QNAME_FEATURE = new QName(NS, "feature");
    
    private static final Log log = LogFactory.getLog(ImplementationFactory.class);
    
    private ImplementationFactory() {}
    
    static Implementation createDefaultImplementation(Loader loader, String className) {
        OMMetaFactory metaFactory = (OMMetaFactory)load(loader, className);
        return metaFactory == null ? null : new Implementation(null, metaFactory,
                new Feature[] { new Feature(OMAbstractFactory.FEATURE_DEFAULT, Integer.MAX_VALUE) });
    }
    
    private static Object load(Loader loader, String className) {
        Class clazz;
        try {
            clazz = loader.load(className);
        } catch (ClassNotFoundException ex) {
            log.error("The class " + className + " could not be loaded", ex);
            return null;
        }
        try {
            return clazz.newInstance();
        } catch (Exception ex) {
            log.error("The class " + className + " could not be instantiated", ex);
            return null;
        }
    }
    
    static List/*<Implementation>*/ parseDescriptor(Loader loader, URL url) {
        List implementations = new ArrayList();
        try {
            // Since this code is used to discover Axiom implementations, we have to use DOM here.
            DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
            dbf.setNamespaceAware(true);
            Element root = dbf.newDocumentBuilder().parse(url.toString()).getDocumentElement();
            QName rootQName = getQName(root);
            if (rootQName.equals(QNAME_IMPLEMENTATIONS)) {
                Node child = root.getFirstChild();
                while (child != null) {
                    if (child instanceof Element) {
                        QName childQName = getQName(child);
                        if (childQName.equals(QNAME_IMPLEMENTATION)) {
                            Implementation implementation = parseImplementation(loader, (Element)child);
                            if (implementation != null) {
                                implementations.add(implementation);
                            }
                        } else {
                            log.warn("Skipping unexpected element " + childQName + "; only "
                                    + QNAME_IMPLEMENTATION + " is expected");
                        }
                    }
                    child = child.getNextSibling();
                }
            } else {
                log.error(url + " is not a valid implementation descriptor: unexpected root element "
                        + rootQName + "; expected " + QNAME_IMPLEMENTATIONS);
            }
        } catch (ParserConfigurationException ex) {
            // If we get here, something went badly wrong
            throw new Error(ex);
        } catch (IOException ex) {
            log.error("Unable to read " + url, ex);
        } catch (SAXException ex) {
            log.error("Parser error while reading " + url, ex);
        }
        return implementations;
    }
    
    private static Implementation parseImplementation(Loader loader, Element implementation) {
        String name = implementation.getAttributeNS(null, "name");
        if (name.length() == 0) {
            log.error("Encountered " + QNAME_IMPLEMENTATION + " element without name attribute");
            return null;
        }
        String loaderClassName = implementation.getAttributeNS(null, "loader");
        if (loaderClassName.length() == 0) {
            log.error("Encountered " + QNAME_IMPLEMENTATION + " element without loader attribute");
            return null;
        }
        OMMetaFactory metaFactory = ((OMMetaFactoryLoader)load(loader, loaderClassName)).load(null);
        if (metaFactory == null) {
            return null;
        }
        List/*<Feature>*/ features = new ArrayList();
        Node child = implementation.getFirstChild();
        while (child != null) {
            if (child instanceof Element) {
                QName childQName = getQName(child);
                if (childQName.equals(QNAME_FEATURE)) {
                    Feature feature = parseFeature((Element)child);
                    if (feature != null) {
                        features.add(feature);
                    }
                } else {
                    log.warn("Skipping unexpected element " + childQName + "; only "
                            + QNAME_FEATURE + " is expected");
                }
            }
            child = child.getNextSibling();
        }
        return new Implementation(name, metaFactory, (Feature[])features.toArray(new Feature[features.size()]));
    }

    private static Feature parseFeature(Element feature) {
        String name = feature.getAttributeNS(null, "name");
        if (name.length() == 0) {
            log.error("Encountered " + QNAME_FEATURE + " element without name attribute");
            return null;
        }
        String priority = feature.getAttributeNS(null, "priority");
        if (priority.length() == 0) {
            log.error("Encountered " + QNAME_FEATURE + " element without priority attribute");
            return null;
        }
        try {
            return new Feature(name, Integer.parseInt(priority));
        } catch (NumberFormatException ex) {
            log.error("Invalid priority value '" + priority + "'; must be an integer");
            return null;
        }
    }
    
    private static QName getQName(Node node) {
        String namespaceURI = node.getNamespaceURI();
        return namespaceURI == null ? new QName(node.getLocalName()) : new QName(namespaceURI, node.getLocalName());
    }
}
