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

import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.net.URI;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

import javax.xml.namespace.QName;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.apache.xerces.dom.DOMInputImpl;
import org.apache.xerces.impl.Constants;
import org.apache.xerces.impl.xs.XMLSchemaLoader;
import org.apache.xerces.impl.xs.util.LSInputListImpl;
import org.apache.xerces.xni.XMLResourceIdentifier;
import org.apache.xerces.xni.XNIException;
import org.apache.xerces.xni.parser.XMLEntityResolver;
import org.apache.xerces.xni.parser.XMLInputSource;
import org.apache.xerces.xs.LSInputList;
import org.apache.xerces.xs.XSModel;
import org.apache.xerces.xs.XSTypeDefinition;
import org.w3c.dom.DOMError;
import org.w3c.dom.DOMErrorHandler;
import org.w3c.dom.ls.LSInput;

/**
 * Xerces based schema model.
 */
public class SchemaModelImpl implements SchemaModel {
    private static final Logger __log = LoggerFactory.getLogger(SchemaModelImpl.class);
    private XSModel _model;

    private SchemaModelImpl(XSModel model) {
        if (model == null) throw new IllegalArgumentException("Null model.");
        _model = model;
    }

    /**
     * Generate a schema model from a collection of schemas.
     * @param schemas collection of schemas (indexed by systemId)
     *
     * @return a {@link SchemaModel}
     */
    public static final SchemaModel newModel(Map<URI, byte[]> schemas) {
        XMLSchemaLoader schemaLoader = new XMLSchemaLoader();
        InternalSchemaResolver resolver = new InternalSchemaResolver();
        schemaLoader.setEntityResolver(resolver);
        schemaLoader.setParameter(Constants.DOM_ERROR_HANDLER, new SchemaErrorHandler());


        final String[] uris = new String[schemas.size()];
        final byte[][] content = new byte[schemas.size()][];

        int idx = 0;
        for (Iterator<Map.Entry<URI,byte[]>> i = schemas.entrySet().iterator();i.hasNext();) {
            Map.Entry<URI, byte[]> me = i.next();
            uris[idx] = me.getKey().toASCIIString();
            content[idx] = me.getValue();
            resolver.put(me.getKey(), me.getValue());
            ++idx;
        }

        LSInput[] inputs = new LSInput[uris.length];
        for (int index = 0; index < uris.length; index++) {
            DOMInputImpl input = new DOMInputImpl(); 
            input.setSystemId(uris[index]); 
            input.setByteStream(new ByteArrayInputStream(content[index])); 
            inputs[index] = input;
        }
        LSInputList list = new LSInputListImpl(inputs, inputs.length);

        XSModel xsm = schemaLoader.loadInputList(list);
        return new SchemaModelImpl(xsm);
    }

    private static class SchemaErrorHandler implements DOMErrorHandler {
        public boolean handleError(DOMError error) {
            boolean isWarning = (error.getSeverity() == DOMError.SEVERITY_WARNING);
            __log.warn("Schema error", ((Exception)error.getRelatedException()));
            __log.warn(error.getLocation().getUri() + ":" + error.getLocation().getLineNumber());
            __log.warn(error.getRelatedData().toString());
            __log.warn(error.getRelatedException().toString());
            return isWarning;
        }
    }

    /**
     * @see org.apache.ode.utils.xsd.SchemaModel#isCompatible(javax.xml.namespace.QName,
     *      javax.xml.namespace.QName)
     */
    public boolean isCompatible(QName type1, QName type2) {
        XSTypeDefinition typeDef1;
        XSTypeDefinition typeDef2;

        if (knowsElementType(type1)) {
            typeDef1 = _model.getElementDeclaration(type1.getLocalPart(),
                    type1.getNamespaceURI())
                    .getTypeDefinition();
        } else if (knowsSchemaType(type1)) {
            typeDef1 = _model.getTypeDefinition(type1.getLocalPart(),
                    type1.getNamespaceURI());
        } else {
            throw new IllegalArgumentException("unknown schema type: " + type1);
        }

        if (knowsElementType(type2)) {
            typeDef2 = _model.getElementDeclaration(type2.getLocalPart(),
                    type2.getNamespaceURI())
                    .getTypeDefinition();
        } else if (knowsSchemaType(type2)) {
            typeDef2 = _model.getTypeDefinition(type2.getLocalPart(),
                    type2.getNamespaceURI());
        } else {
            throw new IllegalArgumentException("unknown schema type: " + type2);
        }

        return typeDef1.derivedFromType(typeDef2, (short)0)
                || typeDef2.derivedFromType(typeDef1, (short)0);
    }

    /**
     * @see org.apache.ode.utils.xsd.SchemaModel#isSimpleType(javax.xml.namespace.QName)
     */
    public boolean isSimpleType(QName type) {
        if (type == null)
            throw new NullPointerException("Null type argument!");

        XSTypeDefinition typeDef = _model.getTypeDefinition(type.getLocalPart(),
                type.getNamespaceURI());

        return (typeDef != null)
                && (typeDef.getTypeCategory() == XSTypeDefinition.SIMPLE_TYPE);
    }

    /**
     * @see org.apache.ode.utils.xsd.SchemaModel#knowsElementType(javax.xml.namespace.QName)
     */
    public boolean knowsElementType(QName elementType) {
        if (elementType == null)
            throw new NullPointerException("Null type argument!");

        return _model.getElementDeclaration(elementType.getLocalPart(),
                elementType.getNamespaceURI()) != null;
    }

    /**
     * @see org.apache.ode.utils.xsd.SchemaModel#knowsSchemaType(javax.xml.namespace.QName)
     */
    public boolean knowsSchemaType(QName schemaType) {
        if (schemaType == null)
            throw new NullPointerException("Null type argument!");

        return _model.getTypeDefinition(schemaType.getLocalPart(),
                schemaType.getNamespaceURI()) != null;
    }


    public static class InternalSchemaResolver implements XMLEntityResolver {
        private Map<String, byte[]> _schemas = new HashMap<String, byte[]>();
        public void put(URI uri, byte[] bytes) {
            _schemas.put(uri.toASCIIString(), bytes);
        }

        public XMLInputSource resolveEntity(XMLResourceIdentifier resourceIdentifier) throws XNIException, IOException {
            XMLInputSource src = new XMLInputSource(resourceIdentifier);
            String location = "";
            if (resourceIdentifier.getNamespace() != null && _schemas.get(resourceIdentifier.getNamespace()) != null)
                location = resourceIdentifier.getNamespace();
            else if (resourceIdentifier.getLiteralSystemId() != null && _schemas.get(resourceIdentifier.getLiteralSystemId()) != null)
                location = resourceIdentifier.getLiteralSystemId();
            else if (resourceIdentifier.getExpandedSystemId() != null && _schemas.get(resourceIdentifier.getExpandedSystemId()) != null)
                location = resourceIdentifier.getExpandedSystemId();
            else if (resourceIdentifier.getBaseSystemId() != null && _schemas.get(resourceIdentifier.getBaseSystemId()) != null)
                location = resourceIdentifier.getBaseSystemId();
            else {
                if (__log.isDebugEnabled()) {
                    __log.debug("Available schemas " + _schemas.keySet());
                }
                throw new IllegalStateException("Schema " + resourceIdentifier + " not captured");
            }

            src.setByteStream(new ByteArrayInputStream(_schemas.get(location)));
            return src;
        }
    }
}
