/*   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.*;
import org.apache.xmlbeans.impl.common.QNameHelper;
import org.apache.xmlbeans.impl.store.Locale;
import org.apache.xmlbeans.impl.xpath.XPathFactory;
import org.w3c.dom.DOMImplementation;
import org.w3c.dom.Node;

import javax.xml.namespace.QName;
import javax.xml.stream.XMLStreamReader;
import java.io.*;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLConnection;
import java.security.DigestInputStream;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.ArrayList;
import java.util.List;

public abstract class SchemaTypeLoaderBase implements SchemaTypeLoader {
    private static final String USER_AGENT = "XMLBeans/" + XmlBeans.getVersion() + " (" + XmlBeans.getTitle() + ")";

    private static String doCompilePath(String pathExpr, XmlOptions options) {
        return XPathFactory.compilePath(pathExpr, options);
    }

    private static String doCompileQuery(String queryExpr, XmlOptions options) {
        return XPathFactory.compileQuery(queryExpr, options);
    }

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

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

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

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

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

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

    public SchemaGlobalAttribute findAttribute(QName name) {
        SchemaGlobalAttribute.Ref ref = findAttributeRef(name);
        if (ref == null) {
            return null;
        }
        SchemaGlobalAttribute result = ref.get();
        assert (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 Locale.newInstance(this, type, options);
    }

    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 Locale.parseToXmlObject(this, xmlText, type, options);
    }

    public XmlObject parse(XMLStreamReader xsr, SchemaType type, XmlOptions options) throws XmlException {
        XmlFactoryHook hook = XmlFactoryHook.ThreadContext.getHook();

        if (hook != null) {
            return hook.parse(this, xsr, type, options);
        }

        return Locale.parseToXmlObject(this, xsr, type, options);
    }

    public XmlObject parse(File file, SchemaType type, XmlOptions options) throws XmlException, IOException {
        String fileName = file.toURI().normalize().toString();
        if (options == null) {
            options = new XmlOptions();
            options.setDocumentSourceName(fileName);
        } else if (options.getDocumentSourceName() == null) {
            options = new XmlOptions(options);
            options.setDocumentSourceName(fileName);
        }

        try (InputStream fis = new FileInputStream(file)) {
            return parse(fis, type, options);
        }
    }

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


        boolean redirected = false;
        int count = 0;
        URLConnection conn;

        do {
            conn = url.openConnection();
            conn.addRequestProperty("User-Agent", USER_AGENT);
            conn.addRequestProperty("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);

        try (InputStream stream = conn.getInputStream()) {
            return parse(stream, type, options);
        }
    }

    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.isLoadMessageDigest()) {
            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 = Locale.parseToXmlObject(this, 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 Locale.parseToXmlObject(this, 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 Locale.parseToXmlObject(this, 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 Locale.newSaxHandler(this, type, options);
    }

    public DOMImplementation newDomImplementation(XmlOptions options) {
        return Locale.newDomImplementation(this, 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.
     * <p>
     * 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<String> 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 : Math.min(nextc, nextd));
            if (next < 0 || next > end) {
                next = end;
            }
            String part = signature.substring(index, next);
            parts.add(part);
            index = next + 1;
        }

        SchemaType curType = null;

        for (int i = parts.size() - 1; i >= 0; i -= 1) {
            String part = 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 (SchemaType subType : subTypes) {
                            SchemaField field = subType.getContainerField();
                            if (field != null && !field.isAttribute() && field.getName().getLocalPart().equals(localName)) {
                                curType = subType;
                                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 (SchemaType subType : subTypes) {
                            SchemaField field = subType.getContainerField();
                            if (field != null && field.isAttribute() && field.getName().getLocalPart().equals(localName)) {
                                curType = subType;
                                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;
    }
}
