/*   Copyright 2004 The Apache Software Foundation
 *
 *   Licensed 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.xmlbeans.impl.schema;

import org.apache.xmlbeans.impl.common.QNameHelper;
import org.apache.xmlbeans.impl.common.IOUtil;
import org.apache.xmlbeans.impl.common.NetUtils;
import org.apache.xmlbeans.impl.values.XmlStore;
import org.apache.xmlbeans.impl.validator.ValidatingXMLInputStream;

import org.apache.xmlbeans.SchemaAttributeGroup;
import org.apache.xmlbeans.SchemaField;
import org.apache.xmlbeans.SchemaGlobalAttribute;
import org.apache.xmlbeans.SchemaGlobalElement;
import org.apache.xmlbeans.SchemaModelGroup;
import org.apache.xmlbeans.SchemaType;
import org.apache.xmlbeans.SchemaTypeLoader;
import org.apache.xmlbeans.XmlBeans;
import org.apache.xmlbeans.XmlSaxHandler;
import org.apache.xmlbeans.XmlException;
import org.apache.xmlbeans.XmlObject;
import org.apache.xmlbeans.XmlOptions;
import org.apache.xmlbeans.XmlFactoryHook;
import org.apache.xmlbeans.XmlRuntimeException;

import java.lang.reflect.Method;
import java.lang.reflect.InvocationTargetException;
import java.io.InputStream;
import java.io.Reader;
import java.io.File;
import java.io.IOException;
import java.io.FileInputStream;
import java.util.List;
import java.util.ArrayList;
import java.net.URL;
import java.net.URLConnection;
import java.net.HttpURLConnection;
import java.security.DigestInputStream;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;

import javax.xml.namespace.QName;

import org.w3c.dom.Node;

import org.apache.xmlbeans.xml.stream.XMLInputStream;
import org.apache.xmlbeans.xml.stream.XMLStreamException;

public abstract class SchemaTypeLoaderBase implements SchemaTypeLoader
{
    private static final Method _rootBuilder = getMethod( "org.apache.xmlbeans.impl.store.Root", "newStore", new Class[] { SchemaTypeLoader.class, SchemaType.class, XmlOptions.class } );
    private static final Method _pathCompiler = getMethod( "org.apache.xmlbeans.impl.store.Path", "getCompiledPath", new Class[] { String.class, XmlOptions.class } );
    private static final Method _queryCompiler = getMethod( "org.apache.xmlbeans.impl.store.Path", "getCompiledQuery", new Class[] { String.class, XmlOptions.class } );

    private static Method getMethod ( String className, String methodName, Class[] args )
    {
        try
        {
            return
                Class.forName( className ).
                    getDeclaredMethod( methodName, args );
        }
        catch (Exception e)
        {
            throw new IllegalStateException(
                "Cannot find " + className + "." + methodName +
                    ".  verify that xmlstore " +
                        "(from xbean.jar) is on classpath" );
        }
    }

    private static Object invokeMethod ( Method method, Object[] args )
    {
        try
        {
            return method.invoke( method, args );
        }
        catch ( InvocationTargetException e )
        {
            XmlRuntimeException ise = new XmlRuntimeException( e.getTargetException().getMessage() );
            ise.initCause( e );
            throw ise;
        }
        catch ( Exception e )
        {
            XmlRuntimeException ise = new XmlRuntimeException( e.getMessage() );
            ise.initCause( e );
            throw ise;
        }
    }

    private XmlStore createNewStore ( SchemaType type, XmlOptions options )
    {
        return
            (XmlStore)
                invokeMethod( _rootBuilder, new Object[] { this, type, options } );
    }

    private static String doCompilePath ( String pathExpr, XmlOptions options ) { return (String) invokeMethod( _pathCompiler, new Object[] { pathExpr, options } ); }
    private static String doCompileQuery ( String queryExpr, XmlOptions options ) { return (String) invokeMethod( _queryCompiler, new Object[] { queryExpr, options } ); }

    public SchemaType findType(QName name)
    {
        SchemaType.Ref ref = findTypeRef(name);
        if (ref == null)
            return null;
        SchemaType result = ref.get();
        if (XmlBeans.ASSERTS)
            XmlBeans.assertTrue(result != null);
        return result;
    }

    public SchemaType findDocumentType(QName name)
    {
        SchemaType.Ref ref = findDocumentTypeRef(name);
        if (ref == null)
            return null;
        SchemaType result = ref.get();
        if (XmlBeans.ASSERTS)
            XmlBeans.assertTrue(result != null);
        return result;
    }

    public SchemaType findAttributeType(QName name)
    {
        SchemaType.Ref ref = findAttributeTypeRef(name);
        if (ref == null)
            return null;
        SchemaType result = ref.get();
        if (XmlBeans.ASSERTS)
            XmlBeans.assertTrue(result != null);
        return result;
    }

    public SchemaModelGroup findModelGroup(QName name)
    {
        SchemaModelGroup.Ref ref = findModelGroupRef(name);
        if (ref == null)
            return null;
        SchemaModelGroup result = ref.get();
        if (XmlBeans.ASSERTS)
            XmlBeans.assertTrue(result != null);
        return result;
    }

    public SchemaAttributeGroup findAttributeGroup(QName name)
    {
        SchemaAttributeGroup.Ref ref = findAttributeGroupRef(name);
        if (ref == null)
            return null;
        SchemaAttributeGroup result = ref.get();
        if (XmlBeans.ASSERTS)
            XmlBeans.assertTrue(result != null);
        return result;
    }

    public SchemaGlobalElement findElement(QName name)
    {
        SchemaGlobalElement.Ref ref = findElementRef(name);
        if (ref == null)
            return null;
        SchemaGlobalElement result = ref.get();
        if (XmlBeans.ASSERTS)
            XmlBeans.assertTrue(result != null);
        return result;
    }

    public SchemaGlobalAttribute findAttribute(QName name)
    {
        SchemaGlobalAttribute.Ref ref = findAttributeRef(name);
        if (ref == null)
            return null;
        SchemaGlobalAttribute result = ref.get();
        if (XmlBeans.ASSERTS)
            XmlBeans.assertTrue(result != null);
        return result;
    }

    //
    //
    //

    public XmlObject newInstance ( SchemaType type, XmlOptions options )
    {
        XmlFactoryHook hook = XmlFactoryHook.ThreadContext.getHook();
        if (hook != null)
            return hook.newInstance( this, type, options );

        return createNewStore( type, options ).getObject();
    }

    public XmlObject parse ( String xmlText, SchemaType type, XmlOptions options ) throws XmlException
    {
        XmlFactoryHook hook = XmlFactoryHook.ThreadContext.getHook();
        if (hook != null)
            return hook.parse( this, xmlText, type, options );

        return createNewStore( null, options ).loadXml( xmlText, type, options );
    }

    public XmlObject parse ( XMLInputStream xis, SchemaType type, XmlOptions options ) throws XmlException, XMLStreamException
    {
        XmlFactoryHook hook = XmlFactoryHook.ThreadContext.getHook();
        if (hook != null)
            return hook.parse( this, xis, type, options );

        return createNewStore( null, options ).loadXml( xis, type, options );
    }

    public XmlObject parse ( File file, SchemaType type, XmlOptions options ) throws XmlException, IOException
    {
        if (options == null)
        {
            options = new XmlOptions();
            options.put( XmlOptions.DOCUMENT_SOURCE_NAME, NetUtils.normalize(IOUtil.fileToURL(file).toString()) );
        }

        else if (! options.hasOption(XmlOptions.DOCUMENT_SOURCE_NAME))
        {
            options = new XmlOptions( options );
            options.put( XmlOptions.DOCUMENT_SOURCE_NAME, NetUtils.normalize(IOUtil.fileToURL(file).toString()) );
        }

        InputStream fis = new FileInputStream( file );

        try
        {
            return parse( fis, type, options );
        }
        finally
        {
            fis.close();
        }
    }

    public XmlObject parse ( URL url, SchemaType type, XmlOptions options ) throws XmlException, IOException
    {
        if (options == null)
        {
            options = new XmlOptions();
            options.put( XmlOptions.DOCUMENT_SOURCE_NAME, url.toString() );
        }

        else if (! options.hasOption(XmlOptions.DOCUMENT_SOURCE_NAME))
        {
            options = new XmlOptions( options );
            options.put( XmlOptions.DOCUMENT_SOURCE_NAME, url.toString() );
        }

        URLConnection conn = null;
        InputStream stream = null;
        download: try
        {

            boolean redirected = false;
            int count = 0;

            do {
                conn = url.openConnection();
                conn.setRequestProperty("User-Agent", "Apache XMLBeans/1.0.3");
                conn.setRequestProperty("Accept", "application/xml, text/xml, */*");
                if (conn instanceof HttpURLConnection)
                {
                    HttpURLConnection httpcon = (HttpURLConnection)conn;
                    int code = httpcon.getResponseCode();
                    redirected = (code == HttpURLConnection.HTTP_MOVED_PERM || code == HttpURLConnection.HTTP_MOVED_TEMP);
                    if (redirected && count > 5)
                        redirected = false;

                    if (redirected)
                    {
                        String newLocation = httpcon.getHeaderField("Location");
                        if (newLocation == null)
                            redirected = false;
                        else
                        {
                            url = new URL(newLocation);
                            count ++;
                        }
                    }
                }
            } while (redirected);

            stream = conn.getInputStream();
            return parse( stream, type, options );
        }
        finally
        {
            if (stream != null)
                stream.close();
        }
    }

    public XmlObject parse ( InputStream jiois, SchemaType type, XmlOptions options ) throws XmlException, IOException
    {
        XmlFactoryHook hook = XmlFactoryHook.ThreadContext.getHook();
        DigestInputStream digestStream = null;
        setupDigest: if (options != null && options.hasOption(XmlOptions.LOAD_MESSAGE_DIGEST))
        {
            MessageDigest sha;
            try
            {
                sha = MessageDigest.getInstance("SHA");
            }
            catch (NoSuchAlgorithmException e)
            {
                break setupDigest;
            }

            digestStream = new DigestInputStream(jiois, sha);
            jiois = digestStream;
        }

        if (hook != null)
            return hook.parse( this, jiois, type, options );

        XmlObject result = createNewStore( null, options ).loadXml( jiois, type, options );

        if (digestStream != null)
            result.documentProperties().setMessageDigest(digestStream.getMessageDigest().digest());

        return result;
    }

    public XmlObject parse ( Reader jior, SchemaType type, XmlOptions options ) throws XmlException, IOException
    {
        XmlFactoryHook hook = XmlFactoryHook.ThreadContext.getHook();
        if (hook != null)
            return hook.parse( this, jior, type, options );

        return createNewStore( null, options ).loadXml( jior, type, options );
    }

    public XmlObject parse ( Node node, SchemaType type, XmlOptions options ) throws XmlException
    {
        XmlFactoryHook hook = XmlFactoryHook.ThreadContext.getHook();
        if (hook != null)
            return hook.parse( this, node, type, options );

        return createNewStore( null, options ).loadXml( node, type, options );
    }

    public XmlSaxHandler newXmlSaxHandler ( SchemaType type, XmlOptions options )
    {
        XmlFactoryHook hook = XmlFactoryHook.ThreadContext.getHook();
        if (hook != null)
            return hook.newXmlSaxHandler( this, type, options );

        return createNewStore( null, options ).newSaxHandler( type, options );
    }

    public XMLInputStream newValidatingXMLInputStream ( XMLInputStream xis, SchemaType type, XmlOptions options ) throws XmlException, XMLStreamException
    {
        return new ValidatingXMLInputStream( xis, this, type, options );
    }

    //
    //
    //

    public String compilePath ( String pathExpr )
    {
        return compilePath( pathExpr, null );
    }

    public String compilePath ( String pathExpr, XmlOptions options )
    {
        return doCompilePath( pathExpr, options );
    }

    public String compileQuery ( String queryExpr )
    {
        return compileQuery( queryExpr, null );
    }

    public String compileQuery ( String queryExpr, XmlOptions options )
    {
        return doCompileQuery( queryExpr, options );
    }

    /**
     * Utility function to load a type from a signature.
     *
     * A signature is the string you get from type.toString().
     */
    public SchemaType typeForSignature(String signature)
    {
        int end = signature.indexOf('@');
        String uri;

        if (end < 0)
        {
            uri = "";
            end = signature.length();
        }
        else
        {
            uri = signature.substring(end + 1);
        }

        List parts = new ArrayList();

        for (int index = 0; index < end; )
        {
            int nextc = signature.indexOf(':', index);
            int nextd = signature.indexOf('|', index);
            int next = (nextc < 0 ? nextd : nextd < 0 ? nextc : nextc < nextd ? nextc : nextd);
            if (next < 0 || next > end)
                next = end;
            String part = signature.substring(index, next);
            parts.add(part);
            index = next + 1;
        }

        SchemaType curType = null;

        outer: for (int i = parts.size() - 1; i >= 0; i -= 1)
        {
            String part = (String)parts.get(i);
            if (part.length() < 1)
                throw new IllegalArgumentException();
            int offset = (part.length() >= 2 && part.charAt(1) == '=') ? 2 : 1;
            cases: switch (part.charAt(0))
            {
                case 'T':
                    if (curType != null)
                        throw new IllegalArgumentException();
                    curType = findType(QNameHelper.forLNS(part.substring(offset), uri));
                    if (curType == null)
                        return null;
                    break;

                case 'D':
                    if (curType != null)
                        throw new IllegalArgumentException();
                    curType = findDocumentType(QNameHelper.forLNS(part.substring(offset), uri));
                    if (curType == null)
                        return null;
                    break;

                case 'C': // deprecated
                case 'R': // current
                    if (curType != null)
                        throw new IllegalArgumentException();
                    curType = findAttributeType(QNameHelper.forLNS(part.substring(offset), uri));
                    if (curType == null)
                        return null;
                    break;

                case 'E':
                case 'U': // distinguish qualified/unqualified TBD
                    if (curType != null)
                    {
                        if (curType.getContentType() < SchemaType.ELEMENT_CONTENT)
                            return null;
                        SchemaType[] subTypes = curType.getAnonymousTypes();
                        String localName = part.substring(offset);
                        for (int j = 0; j < subTypes.length; j++)
                        {
                            SchemaField field = subTypes[j].getContainerField();
                            if (field != null && !field.isAttribute() && field.getName().getLocalPart().equals(localName))
                            {
                                curType = subTypes[j];
                                break cases;
                            }
                        }
                        return null;
                    }
                    else
                    {
                        SchemaGlobalElement elt = findElement(QNameHelper.forLNS(part.substring(offset), uri));
                        if (elt == null)
                            return null;
                        curType = elt.getType();
                    }
                    break;

                case 'A':
                case 'Q': // distinguish qualified/unqualified TBD
                    if (curType != null)
                    {
                        if (curType.isSimpleType())
                            return null;
                        SchemaType[] subTypes = curType.getAnonymousTypes();
                        String localName = part.substring(offset);
                        for (int j = 0; j < subTypes.length; j++)
                        {
                            SchemaField field = subTypes[j].getContainerField();
                            if (field != null && field.isAttribute() && field.getName().getLocalPart().equals(localName))
                            {
                                curType = subTypes[j];
                                break cases;
                            }
                        }
                        return null;
                    }
                    else
                    {
                        SchemaGlobalAttribute attr = findAttribute(QNameHelper.forLNS(part.substring(offset), uri));
                        if (attr == null)
                            return null;
                        curType = attr.getType();
                    }
                    break;

                case 'B':
                    if (curType == null)
                    {
                        throw new IllegalArgumentException();
                    }
                    else
                    {
                        if (curType.getSimpleVariety() != SchemaType.ATOMIC)
                            return null;
                        SchemaType[] subTypes = curType.getAnonymousTypes();
                        if (subTypes.length != 1)
                            return null;
                        curType = subTypes[0];
                    }
                    break;

                case 'I':
                    if (curType == null)
                    {
                        throw new IllegalArgumentException();
                    }
                    else
                    {
                        if (curType.getSimpleVariety() != SchemaType.LIST)
                            return null;
                        SchemaType[] subTypes = curType.getAnonymousTypes();
                        if (subTypes.length != 1)
                            return null;
                        curType = subTypes[0];
                    }
                    break;

                case 'M':
                    if (curType == null)
                    {
                        throw new IllegalArgumentException();
                    }
                    else
                    {
                        int index;
                        try
                        {
                            index = Integer.parseInt(part.substring(offset));
                        }
                        catch (Exception e)
                        {
                            throw new IllegalArgumentException();
                        }

                        if (curType.getSimpleVariety() != SchemaType.UNION)
                            return null;
                        SchemaType[] subTypes = curType.getAnonymousTypes();
                        if (subTypes.length <= index)
                            return null;
                        curType = subTypes[index];
                    }
                    break;

                default:
                    throw new IllegalArgumentException();
            }
        }
        return curType;
    }
}
