/*   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.SystemCache;
import org.apache.xmlbeans.impl.common.QNameHelper;
import org.apache.xmlbeans.impl.common.XBeanDebug;
import org.apache.xmlbeans.impl.xb.xsdschema.SchemaDocument;

import javax.xml.namespace.QName;

import java.io.InputStream;
import java.util.Map;
import java.util.HashMap;
import java.util.Collections;
import java.util.ArrayList;
import java.util.List;
import java.util.IdentityHashMap;

import java.lang.ref.SoftReference;

import static org.apache.xmlbeans.impl.schema.SchemaTypeSystemImpl.METADATA_PACKAGE_GEN;

public class SchemaTypeLoaderImpl extends SchemaTypeLoaderBase {
    private ResourceLoader _resourceLoader;
    private ClassLoader _classLoader;
    private final SchemaTypeLoader[] _searchPath;

    private Map _classpathTypeSystems;
    private Map _classLoaderTypeSystems;
    private Map _elementCache;
    private Map _attributeCache;
    private Map _modelGroupCache;
    private Map _attributeGroupCache;
    private Map _idConstraintCache;
    private Map _typeCache;
    private Map _documentCache;
    private Map _attributeTypeCache;
    private Map _classnameCache;
    private final String _metadataPath;

    public static String METADATA_PACKAGE_LOAD = METADATA_PACKAGE_GEN;
    private static final Object CACHED_NOT_FOUND = new Object();

    private static final String[] basePackage = { "org.apache.xmlbeans.metadata", "schemaorg_apache_xmlbeans" };
    private static final String[] baseSchemas = { "sXMLCONFIG", "sXMLLANG", "sXMLSCHEMA", "sXMLTOOLS" };




    private static class SchemaTypeLoaderCache extends SystemCache
    {
        // The following maintains a cache of SchemaTypeLoaders per ClassLoader per Thread.
        // I use soft references to allow the garbage collector to reclain the type loaders
        // and/pr class loaders at will.

        private ThreadLocal _cachedTypeSystems =
            new ThreadLocal() { protected Object initialValue() { return new ArrayList(); } };

        @Override
        public void clearThreadLocals() {
            _cachedTypeSystems.remove();

            super.clearThreadLocals();
        }

        public SchemaTypeLoader getFromTypeLoaderCache(ClassLoader cl)
        {
            ArrayList a = (ArrayList) _cachedTypeSystems.get();

            int candidate = -1;
            SchemaTypeLoaderImpl result = null;

            for ( int i = 0 ; i < a.size() ; i++ )
            {
                SchemaTypeLoaderImpl tl = (SchemaTypeLoaderImpl) ((SoftReference) a.get(i)).get();

                if (tl == null)
                {
                    assert i > candidate;
                    a.remove(i--);
                }
                else if (tl._classLoader == cl)
                {
                    assert candidate == -1 && result == null;

                    candidate = i;
                    result = tl;

                    break;
                }
            }

            // Make sure the most recently accessed entry is at the beginning of the array

            if (candidate > 0)
            {
                Object t = a.get(0);
                a.set(0, a.get(candidate));
                a.set(candidate, t);
            }

            return result;
        }

        public void addToTypeLoaderCache(SchemaTypeLoader stl, ClassLoader cl)
        {
            assert (stl instanceof SchemaTypeLoaderImpl) &&
                   ((SchemaTypeLoaderImpl) stl)._classLoader == cl;

            ArrayList a = (ArrayList) _cachedTypeSystems.get();
            // Make sure this entry is at the top of the stack
            if (a.size() > 0)
            {
                Object t = a.get(0);
                a.set(0, new SoftReference(stl));
                a.add(t);
            }
            else
                a.add(new SoftReference(stl));
        }
    }

    public static SchemaTypeLoaderImpl getContextTypeLoader ( )
    {
        ClassLoader cl = Thread.currentThread().getContextClassLoader();
        SchemaTypeLoaderImpl result = (SchemaTypeLoaderImpl)
            SystemCache.get().getFromTypeLoaderCache(cl);

        if (result == null)
        {
            result =
                new SchemaTypeLoaderImpl(
                    new SchemaTypeLoader[]{BuiltinSchemaTypeSystem.get()}, null, cl, null);
            SystemCache.get().addToTypeLoaderCache(result, cl);
        }

        return result;
    }

    public static SchemaTypeLoader build(SchemaTypeLoader[] searchPath, ResourceLoader resourceLoader, ClassLoader classLoader) {
        return build(searchPath, resourceLoader, classLoader, null);
    }

    /**
     * Initialize a SchemaTypeLoader via the given loaders and paths
     *
     * @param searchPath the searchPath to use
     * @param resourceLoader the resourceLoader to use
     * @param classLoader the classLoader to use
     * @param metadataPath the custom metadata path
     * @return the schemaTypeLoader
     *
     * @since XmlBeans 3.1.0
     */
    public static SchemaTypeLoader build(final SchemaTypeLoader[] searchPath, ResourceLoader resourceLoader, ClassLoader classLoader, String metadataPath) {
        // assemble a flattened search path with no duplicates
        SubLoaderList list = new SubLoaderList();

        list.add(searchPath);

        ClassLoader cl = (classLoader == null) ? SchemaDocument.class.getClassLoader() :  classLoader;

        for (String prefix : basePackage) {
            for (String holder : baseSchemas) {
                String clName = prefix + ".system." + holder + ".TypeSystemHolder";
                if (cl.getResource(clName.replace(".","/")+".class") == null) {
                    // if the first class isn't found in the package, continue with the next package
                    break;
                }
                try {
                    Class cls = Class.forName(clName, true, cl);
                    list.add((SchemaTypeLoader)cls.getDeclaredField("typeSystem").get(null));
                } catch (Exception e) {
                    throw new XmlRuntimeException(e);
                }
            }
        }

        return new SchemaTypeLoaderImpl(list.toArray(), resourceLoader, classLoader, metadataPath);
    }

    /**
     * Just used to avoid duplicate path entries
     */
    private static class SubLoaderList
    {
        private final List<SchemaTypeLoader> theList = new ArrayList<SchemaTypeLoader>();
        private final Map<SchemaTypeLoader,Object> seen = new IdentityHashMap<SchemaTypeLoader,Object>();

        void add(SchemaTypeLoader[] searchPath) {
            if (searchPath == null) {
                return;
            }
            for (SchemaTypeLoader stl : searchPath) {
                if (stl instanceof SchemaTypeLoaderImpl) {
                    SchemaTypeLoaderImpl sub = (SchemaTypeLoaderImpl)stl;
                    if (sub._classLoader != null || sub._resourceLoader != null) {
                        add(sub);
                    } else {
                        add(sub._searchPath);
                    }
                } else {
                    add(stl);
                }
            }
        }

        void add(SchemaTypeLoader loader) {
            if (loader != null && !seen.containsKey(loader)) {
                theList.add(loader);
                seen.put(loader, null);
            }
        }

        SchemaTypeLoader[] toArray() {
            return theList.toArray(EMPTY_SCHEMATYPELOADER_ARRAY);
        }
    }

    /**
     * Constructs a SchemaTypeLoaderImpl that searches for objects
     * in the following order:
     *
     * (1) First on the searchPath of other SchemaTypeSystems supplied,
     *     in order that they are listed.
     * (2) Next on the classpath of .jar files or directories supplied,
     *     in the order that they are listed. When types are returned in
     *     this way, they are instantiated from a private typesystem.
     *     In other words, if a type is loaded from another SchemaTypeLoaderImpl
     *     that was initialized on the same file, the instance of the type will
     *     be different.
     * (3) Finally on the classloader supplied.
     */
    private SchemaTypeLoaderImpl(SchemaTypeLoader[] searchPath, ResourceLoader resourceLoader, ClassLoader classLoader, String metadataPath)
    {
        _searchPath = (searchPath == null) ? EMPTY_SCHEMATYPELOADER_ARRAY : searchPath;
        _resourceLoader = resourceLoader;
        _classLoader = classLoader;

        if (metadataPath != null) {
            this._metadataPath = metadataPath;
        } else {
            final String path26 = "schema" + METADATA_PACKAGE_LOAD.replace("/","_");
            this._metadataPath = (isPath30(_classLoader)) ? METADATA_PACKAGE_LOAD : path26;
        }

        initCaches();
    }

    private static boolean isPath30(ClassLoader loader) {
        final String path30 = METADATA_PACKAGE_LOAD + "/system";
        final ClassLoader cl = (loader != null) ? loader : SchemaDocument.class.getClassLoader();
        return cl.getResource(path30) != null;
    }

    /**
     * Initializes the caches.
     */
    private final void initCaches()
    {
        _classpathTypeSystems = Collections.synchronizedMap(new HashMap());
        _classLoaderTypeSystems = Collections.synchronizedMap(new HashMap());
        _elementCache = Collections.synchronizedMap(new HashMap());
        _attributeCache = Collections.synchronizedMap(new HashMap());
        _modelGroupCache = Collections.synchronizedMap(new HashMap());
        _attributeGroupCache = Collections.synchronizedMap(new HashMap());
        _idConstraintCache = Collections.synchronizedMap(new HashMap());
        _typeCache = Collections.synchronizedMap(new HashMap());
        _documentCache = Collections.synchronizedMap(new HashMap());
        _attributeTypeCache = Collections.synchronizedMap(new HashMap());
        _classnameCache = Collections.synchronizedMap(new HashMap());
    }

    SchemaTypeSystemImpl typeSystemForComponent(String searchdir, QName name)
    {
        String searchfor = searchdir + QNameHelper.hexsafedir(name) + ".xsb";
        String tsname = null;

        if (_resourceLoader != null)
            tsname = crackEntry(_resourceLoader, searchfor);

        if (_classLoader != null)
            tsname = crackEntry(_classLoader, searchfor);

        if (tsname != null)
            return (SchemaTypeSystemImpl)typeSystemForName(tsname);

        return null;
    }

    public SchemaTypeSystem typeSystemForName(String name)
    {
        if (_resourceLoader != null)
        {
            SchemaTypeSystem result = getTypeSystemOnClasspath(name);
            if (result != null)
                return result;
        }

        if (_classLoader != null)
        {
            SchemaTypeSystem result = getTypeSystemOnClassloader(name);
            if (result != null)
                return result;
        }
        return null;
    }

    SchemaTypeSystemImpl typeSystemForClassname(String searchdir, String name)
    {
        String searchfor = searchdir + name.replace('.', '/') + ".xsb";

        if (_resourceLoader != null)
        {
            String tsname = crackEntry(_resourceLoader, searchfor);
            if (tsname != null)
                return getTypeSystemOnClasspath(tsname);
        }

        if (_classLoader != null)
        {
            String tsname = crackEntry(_classLoader, searchfor);
            if (tsname != null)
                return getTypeSystemOnClassloader(tsname);
        }

        return null;
    }

    SchemaTypeSystemImpl getTypeSystemOnClasspath(String name)
    {
        SchemaTypeSystemImpl result = (SchemaTypeSystemImpl)_classpathTypeSystems.get(name);
        if (result == null)
        {
            result = new SchemaTypeSystemImpl(_resourceLoader, name, this);
            _classpathTypeSystems.put(name, result);
        }
        return result;
    }

    SchemaTypeSystemImpl getTypeSystemOnClassloader(String name)
    {
        XBeanDebug.trace(XBeanDebug.TRACE_SCHEMA_LOADING, "Finding type system " + name + " on classloader", 0);
        SchemaTypeSystemImpl result = (SchemaTypeSystemImpl)_classLoaderTypeSystems.get(name);
        if (result == null)
        {
            XBeanDebug.trace(XBeanDebug.TRACE_SCHEMA_LOADING, "Type system " + name + " not cached - consulting field", 0);
            result = SchemaTypeSystemImpl.forName(name, _classLoader);
            _classLoaderTypeSystems.put(name, result);
        }
        return result;
    }

    static String crackEntry(ResourceLoader loader, String searchfor)
    {
        InputStream is = loader.getResourceAsStream(searchfor);
        if (is == null)
            return null;
        return crackPointer(is);
    }

    static String crackEntry(ClassLoader loader, String searchfor)
    {
        InputStream stream = loader.getResourceAsStream(searchfor);
        if (stream == null)
            return null;
        return crackPointer(stream);
    }

    static String crackPointer(InputStream stream)
    {
        return SchemaTypeSystemImpl.crackPointer(stream);
    }

    public boolean isNamespaceDefined(String namespace)
    {
        for (int i = 0; i < _searchPath.length; i++)
            if (_searchPath[i].isNamespaceDefined(namespace))
                return true;

        SchemaTypeSystem sts = typeSystemForComponent(_metadataPath + "/namespace/", new QName(namespace, "xmlns"));
        return (sts != null);
    }

    public SchemaType.Ref findTypeRef(QName name)
    {
        /**
         * The maps are synchronized, we use two accesses to the cache (one read
         * and one write), but the code inbetween is not synchronized. The
         * assumption is that the underlying datastructures (the search path and
         * the classloader) do not change, so two threads running the code in
         * parallel will come up with the same result.
         */
        Object cached = _typeCache.get(name);
        if (cached == CACHED_NOT_FOUND)
            return null;
        SchemaType.Ref result = (SchemaType.Ref) cached;
        if (result == null)
        {
            for (int i = 0; i < _searchPath.length; i++)
                if (null != (result = _searchPath[i].findTypeRef(name)))
                    break;
            if (result == null)
            {
                SchemaTypeSystem ts = typeSystemForComponent(_metadataPath + "/type/", name);
                if (ts != null)
                {
                    result = ts.findTypeRef(name);
                    assert(result != null) : "Type system registered type " + QNameHelper.pretty(name) + " but does not return it";
                }
            }
            _typeCache.put(name, result == null ? CACHED_NOT_FOUND : result);
        }
        return result;
    }

    public SchemaType typeForClassname(String classname)
    {
        classname = classname.replace('$', '.');

        Object cached = _classnameCache.get(classname);
        if (cached == CACHED_NOT_FOUND)
            return null;
        SchemaType result = (SchemaType) cached;
        if (result == null)
        {
            for (int i = 0; i < _searchPath.length; i++)
                if (null != (result = _searchPath[i].typeForClassname(classname)))
                    break;
            if (result == null)
            {
                SchemaTypeSystem ts = typeSystemForClassname(_metadataPath + "/javaname/", classname);
                if (ts != null)
                {
                    result = ts.typeForClassname(classname);
                    assert(result != null) : "Type system registered type " + classname + " but does not return it";
                }
            }
            _classnameCache.put(classname, result == null ? CACHED_NOT_FOUND : result);
        }
        return result;
    }

    public SchemaType.Ref findDocumentTypeRef(QName name)
    {
        Object cached = _documentCache.get(name);
        if (cached == CACHED_NOT_FOUND)
            return null;
        SchemaType.Ref result = (SchemaType.Ref) cached;
        if (result == null)
        {
            for (int i = 0; i < _searchPath.length; i++)
                if (null != (result = _searchPath[i].findDocumentTypeRef(name)))
                    break;
            if (result == null)
            {
                SchemaTypeSystem ts = typeSystemForComponent(_metadataPath + "/element/", name);
                if (ts != null)
                {
                    result = ts.findDocumentTypeRef(name);
                    assert(result != null) : "Type system registered element " + QNameHelper.pretty(name) + " but does not contain document type";
                }
            }
            _documentCache.put(name, result == null ? CACHED_NOT_FOUND : result);
        }
        return result;
    }

    public SchemaType.Ref findAttributeTypeRef(QName name)
    {
        Object cached = _attributeTypeCache.get(name);
        if (cached == CACHED_NOT_FOUND)
            return null;
        SchemaType.Ref result = (SchemaType.Ref) cached;
        if (result == null)
        {
            for (int i = 0; i < _searchPath.length; i++)
                if (null != (result = _searchPath[i].findAttributeTypeRef(name)))
                    break;
            if (result == null)
            {
                SchemaTypeSystem ts = typeSystemForComponent(_metadataPath + "/attribute/", name);
                if (ts != null)
                {
                    result = ts.findAttributeTypeRef(name);
                    assert(result != null) : "Type system registered attribute " + QNameHelper.pretty(name) + " but does not contain attribute type";
                }
            }
            _attributeTypeCache.put(name, result == null ? CACHED_NOT_FOUND : result);
        }
        return result;
    }

    public SchemaGlobalElement.Ref findElementRef(QName name)
    {
        Object cached = _elementCache.get(name);
        if (cached == CACHED_NOT_FOUND)
            return null;
        SchemaGlobalElement.Ref result = (SchemaGlobalElement.Ref) cached;
        if (result == null)
        {
            for (int i = 0; i < _searchPath.length; i++)
                if (null != (result = _searchPath[i].findElementRef(name)))
                    break;
            if (result == null)
            {
                SchemaTypeSystem ts = typeSystemForComponent(_metadataPath + "/element/", name);
                if (ts != null)
                {
                    result = ts.findElementRef(name);
                    assert(result != null) : "Type system registered element " + QNameHelper.pretty(name) + " but does not return it";
                }
            }
            _elementCache.put(name, result == null ? CACHED_NOT_FOUND : result);
        }
        return result;
    }

    public SchemaGlobalAttribute.Ref findAttributeRef(QName name)
    {
        Object cached = _attributeCache.get(name);
        if (cached == CACHED_NOT_FOUND)
            return null;
        SchemaGlobalAttribute.Ref result = (SchemaGlobalAttribute.Ref) cached;
        if (result == null)
        {
            for (int i = 0; i < _searchPath.length; i++)
                if (null != (result = _searchPath[i].findAttributeRef(name)))
                    break;
            if (result == null)
            {
                SchemaTypeSystem ts = typeSystemForComponent(_metadataPath + "/attribute/", name);
                if (ts != null)
                {
                    result = ts.findAttributeRef(name);
                    assert(result != null) : "Type system registered attribute " + QNameHelper.pretty(name) + " but does not return it";
                }
            }
            _attributeCache.put(name, result == null ? CACHED_NOT_FOUND : result);
        }
        return result;
    }

    public SchemaModelGroup.Ref findModelGroupRef(QName name)
    {
        Object cached = _modelGroupCache.get(name);
        if (cached == CACHED_NOT_FOUND)
            return null;
        SchemaModelGroup.Ref result = (SchemaModelGroup.Ref) cached;
        if (result == null)
        {
            for (int i = 0; i < _searchPath.length; i++)
                if (null != (result = _searchPath[i].findModelGroupRef(name)))
                    break;
            if (result == null)
            {
                SchemaTypeSystem ts = typeSystemForComponent(_metadataPath + "/modelgroup/", name);
                if (ts != null)
                {
                    result = ts.findModelGroupRef(name);
                    assert(result != null) : "Type system registered model group " + QNameHelper.pretty(name) + " but does not return it";
                }
            }
            _modelGroupCache.put(name, result == null ? CACHED_NOT_FOUND : result);
        }
        return result;
    }

    public SchemaAttributeGroup.Ref findAttributeGroupRef(QName name)
    {
        Object cached = _attributeGroupCache.get(name);
        if (cached == CACHED_NOT_FOUND)
            return null;
        SchemaAttributeGroup.Ref result = (SchemaAttributeGroup.Ref) cached;
        if (result == null)
        {
            for (int i = 0; i < _searchPath.length; i++)
                if (null != (result = _searchPath[i].findAttributeGroupRef(name)))
                    break;
            if (result == null)
            {
                SchemaTypeSystem ts = typeSystemForComponent(_metadataPath + "/attributegroup/", name);
                if (ts != null)
                {
                    result = ts.findAttributeGroupRef(name);
                    assert(result != null) : "Type system registered attribute group " + QNameHelper.pretty(name) + " but does not return it";
                }
            }
            _attributeGroupCache.put(name, result == null ? CACHED_NOT_FOUND : result);
        }
        return result;
    }

    public SchemaIdentityConstraint.Ref findIdentityConstraintRef(QName name)
    {
        Object cached = _idConstraintCache.get(name);
        if (cached == CACHED_NOT_FOUND)
            return null;
        SchemaIdentityConstraint.Ref result = (SchemaIdentityConstraint.Ref) cached;
        if (result == null)
        {
            for (int i = 0; i < _searchPath.length; i++)
                if (null != (result = _searchPath[i].findIdentityConstraintRef(name)))
                    break;
            if (result == null)
            {
                SchemaTypeSystem ts = typeSystemForComponent(_metadataPath + "/identityconstraint/", name);
                if (ts != null)
                {
                    result = ts.findIdentityConstraintRef(name);
                    assert(result != null) : "Type system registered identity constraint " + QNameHelper.pretty(name) + " but does not return it";
                }
            }
            _idConstraintCache.put(name, result == null ? CACHED_NOT_FOUND : result);
        }
        return result;
    }

    public InputStream getSourceAsStream(String sourceName)
    {
        InputStream result = null;

        if (!sourceName.startsWith("/"))
            sourceName = "/" + sourceName;

        if (_resourceLoader != null)
            result = _resourceLoader.getResourceAsStream(_metadataPath + "/src" + sourceName);

        if (result == null && _classLoader != null)
            return _classLoader.getResourceAsStream(_metadataPath + "/src" + sourceName);

        return result;
    }

    private static final SchemaTypeLoader[] EMPTY_SCHEMATYPELOADER_ARRAY = new SchemaTypeLoader[0];

    static
    {
        if (SystemCache.get() instanceof SystemCache)
            SystemCache.set(new SchemaTypeLoaderCache());
    }
}
