/*
 * 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.ode.jbi.util;

import java.net.URI;
import java.util.Collection;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.apache.ode.utils.XMLParserUtils;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.InputSource;

/**
 * Collection of schemas.
 *
 * @author gnodet
 */
public class SchemaCollection {

    private static Logger log = LoggerFactory.getLogger(SchemaCollection.class);

    private Map schemas;
    private URI baseUri;

    public SchemaCollection() {
        this(null);
    }

    public SchemaCollection(URI baseUri) {
        if (log.isDebugEnabled()) {
            log.debug("Initializing schema collection with baseUri: " + baseUri);
        }
        this.baseUri = baseUri;
        this.schemas = new HashMap();
    }

    public Schema getSchema(String namespaceURI) {
        return (Schema) schemas.get(namespaceURI);
    }

    public void read(Element elem, URI sourceUri) throws Exception {
        Schema schema = new Schema();
        schema.setSourceUri(sourceUri);
        schema.setRoot(elem);
        schema.setNamespace(elem.getAttribute("targetNamespace"));
        schemas.put(schema.getNamespace(), schema);
        handleImports(schema);
    }

    public void read(String location, URI baseUri) throws Exception {
        if (log.isDebugEnabled()) {
            log.debug("Reading schema at '" + location + "' with baseUri '" + baseUri + "'");
        }
        if (baseUri == null) {
            baseUri = this.baseUri;
        }
        URI loc;
        if (baseUri != null) {
            loc = resolve(baseUri, location);
            if (!loc.isAbsolute()) {
                throw new IllegalArgumentException("Unable to resolve '" + loc.toString() + "' relative to '" + baseUri + "'");
            }
        } else {
            loc = new URI(location);
            if (!loc.isAbsolute()) {
                throw new IllegalArgumentException("Location '" + loc.toString() + "' is not absolute and no baseUri specified");
            }
        }
        InputSource inputSource = new InputSource();
        inputSource.setByteStream(loc.toURL().openStream());
        inputSource.setSystemId(loc.toString());
        read(inputSource);
    }

    public void read(InputSource inputSource) throws Exception {
        DocumentBuilderFactory docFac = XMLParserUtils.getDocumentBuilderFactory(); // don't trust system provided parser!
        docFac.setNamespaceAware(true);
        DocumentBuilder builder = docFac.newDocumentBuilder();
        Document doc = builder.parse(inputSource);
        read(doc.getDocumentElement(),
             inputSource.getSystemId() != null ? new URI(inputSource.getSystemId()) : null);
    }

    protected void handleImports(Schema schema) throws Exception {
        NodeList children = schema.getRoot().getChildNodes();
        List imports = new ArrayList();
        for (int i = 0; i < children.getLength(); i++) {
            Node child = children.item(i);
            if (child instanceof Element) {
                Element ce = (Element) child;
                if ("http://www.w3.org/2001/XMLSchema".equals(ce.getNamespaceURI()) &&
                    "import".equals(ce.getLocalName())) {
                    imports.add(ce);
                }
            }
        }
        for (Iterator iter = imports.iterator(); iter.hasNext();) {
            Element ce = (Element) iter.next();
            String namespace = ce.getAttribute("namespace");
            if (schemas.get(namespace) == null) {
                String location = ce.getAttribute("schemaLocation");
                if (location != null && !"".equals(location)) {
                    read(location, schema.getSourceUri());
                }
            }
            schema.addImport(namespace);
            schema.getRoot().removeChild(ce);
        }
    }

    protected static URI resolve(URI base, String location) {
        if ("jar".equals(base.getScheme())) {
            String str = base.toString();
            String[] parts = str.split("!");
            parts[1] = URI.create(parts[1]).resolve(location).toString();
            return URI.create(parts[0] + "!" + parts[1]);
        }
        return base.resolve(location);
    }

    public int getSize() {
        if (schemas != null) {
           return schemas.size();
        } else {
           return 0;
        }
     }

     public Collection getSchemas() {
        if (schemas != null) {
           return schemas.values();
        } else {
           return java.util.Collections.EMPTY_SET;
        }
     }
}
