/*   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.SchemaTypeLoader;
import org.apache.xmlbeans.SchemaType;
import org.apache.xmlbeans.SchemaGlobalElement;
import org.apache.xmlbeans.SchemaGlobalAttribute;
import org.apache.xmlbeans.SchemaModelGroup;
import org.apache.xmlbeans.SchemaAttributeGroup;
import org.apache.xmlbeans.SchemaTypeSystem;
import org.apache.xmlbeans.SchemaIdentityConstraint;
import org.apache.xmlbeans.ResourceLoader;
import org.apache.xmlbeans.impl.common.SystemCache;
import org.apache.xmlbeans.impl.common.QNameHelper;
import org.apache.xmlbeans.impl.common.XBeanDebug;
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 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 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) {
        final SchemaTypeLoader[] sp;

        if (searchPath == null) {
            // if the metadata directory is customized, fallback to the xmlbeans typesystems
            final boolean isDefaultPath = (metadataPath == null || ("schema" + METADATA_PACKAGE_GEN).equals(metadataPath));
            if (isDefaultPath) {
                sp = null;
            } else {
                String[] baseHolder = {
                    "schemaorg_apache_xmlbeans.system.sXMLCONFIG.TypeSystemHolder",
                    "schemaorg_apache_xmlbeans.system.sXMLLANG.TypeSystemHolder",
                    "schemaorg_apache_xmlbeans.system.sXMLSCHEMA.TypeSystemHolder",
                    "schemaorg_apache_xmlbeans.system.sXMLTOOLS.TypeSystemHolder"
                };

                sp = new SchemaTypeLoader[baseHolder.length];
                for (int i=0; i<baseHolder.length; i++) {
                    try {
                        Class cls = Class.forName(baseHolder[i]);
                        sp[i] = (SchemaTypeLoader)cls.getDeclaredField("typeSystem").get(null);
                    } catch (Exception e) {
                        System.out.println("throw runtime: "+e.toString());
                        throw new RuntimeException(e);
                    }
                }
            }
        } else {
            // assemble a flattened search path with no duplicates
            SubLoaderList list = new SubLoaderList();
            list.add(searchPath);
            sp = list.toArray();
        }

        if (sp != null && sp.length == 1 && resourceLoader == null && classLoader == null) {
            return sp[0];
        }

        return new SchemaTypeLoaderImpl(sp, 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)
    {
        if (searchPath == null)
            _searchPath = EMPTY_SCHEMATYPELOADER_ARRAY;
        else
            _searchPath = searchPath;
        _resourceLoader = resourceLoader;
        _classLoader = classLoader;
        this._metadataPath = (metadataPath == null) ? "schema" + METADATA_PACKAGE_LOAD : metadataPath;

        initCaches();
    }

    /**
     * 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());
    }
}
