/*   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.common.ResolverUtil;
import org.apache.xmlbeans.impl.util.HexBin;
import org.apache.xmlbeans.impl.values.XmlStringImpl;
import org.apache.xmlbeans.impl.values.XmlValueOutOfRangeException;
import org.apache.xmlbeans.impl.xb.xsdschema.SchemaDocument;
import org.xml.sax.EntityResolver;

import javax.xml.namespace.QName;
import java.io.File;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.URL;
import java.nio.charset.StandardCharsets;
import java.util.*;
import java.util.function.Consumer;

/**
 * This class represents the state of the SchemaTypeSystemCompiler as it's
 * going.
 */
public class StscState {
    private final static XmlValueRef XMLSTR_PRESERVE = buildString("preserve");
    private final static XmlValueRef XMLSTR_REPLACE = buildString("preserve");
    private final static XmlValueRef XMLSTR_COLLAPSE = buildString("preserve");

    static final SchemaType[] EMPTY_ST_ARRAY = new SchemaType[0];

    private static final XmlValueRef[] FACETS_NONE = new XmlValueRef[12];
    private static final boolean[] FIXED_FACETS_NONE = new boolean[12];
    private static final boolean[] FIXED_FACETS_WS = new boolean[12];

    private static final XmlValueRef[] FACETS_WS_COLLAPSE = {
        null, null, null, null, null, null, null, null, null,
        build_wsstring(SchemaType.WS_COLLAPSE), null, null
    };


    final static XmlValueRef[] FACETS_UNION = FACETS_NONE;
    final static boolean[] FIXED_FACETS_UNION = FIXED_FACETS_NONE;
    final static XmlValueRef[] FACETS_LIST = FACETS_WS_COLLAPSE;
    final static boolean[] FIXED_FACETS_LIST = FIXED_FACETS_WS;

    private static final ThreadLocal<StscStack> tl_stscStack = new ThreadLocal<>();

    private final static String PROJECT_URL_PREFIX = "project://local";


    private String _givenStsName;
    private Collection<XmlError> _errorListener;
    private SchemaTypeSystemImpl _target;
    private BindingConfig _config;
    private Map<QName, QName> _compatMap;
    private boolean _doingDownloads;
    private byte[] _digest = null;
    private boolean _noDigest = false;

    // EXPERIMENTAL: recovery from compilation errors and partial type systems
    private boolean _allowPartial = false;
    private int _recoveredErrors = 0;

    private SchemaTypeLoader _importingLoader;

    private final Map<String, SchemaContainer> _containers = new LinkedHashMap<>();
    private SchemaDependencies _dependencies;

    private Map _redefinedGlobalTypes = new LinkedHashMap();
    private Map _redefinedModelGroups = new LinkedHashMap();
    private Map _redefinedAttributeGroups = new LinkedHashMap();

    private final Map<QName, SchemaType> _globalTypes = new LinkedHashMap<>();
    private final Map<QName, SchemaGlobalElement> _globalElements = new LinkedHashMap<>();
    private final Map<QName, SchemaGlobalAttribute> _globalAttributes = new LinkedHashMap<>();
    private final Map<QName, SchemaModelGroup> _modelGroups = new LinkedHashMap<>();
    private final Map<QName, SchemaAttributeGroup> _attributeGroups = new LinkedHashMap<>();
    private final Map<QName, SchemaType> _documentTypes = new LinkedHashMap<>();
    private final Map<QName, SchemaType> _attributeTypes = new LinkedHashMap<>();
    private final Map<String, SchemaType> _typesByClassname = new LinkedHashMap<>();
    private final Map<String, SchemaComponent> _misspelledNames = new HashMap<>();
    private final Set<SchemaComponent> _processingGroups = new LinkedHashSet<>();
    private final Map<QName, SchemaIdentityConstraint> _idConstraints = new LinkedHashMap<>();
    private final Set<String> _namespaces = new HashSet<>();
    private final List<SchemaAnnotation> _annotations = new ArrayList<>();
    private boolean _noUpa;
    private boolean _noPvr;
    private boolean _noAnn;
    private boolean _mdefAll;
    private final Set<String> _mdefNamespaces = buildDefaultMdefNamespaces();
    private EntityResolver _entityResolver;
    private File _schemasDir;


    private final Map<String, String> _sourceForUri = new HashMap<>();
    private URI _baseURI = URI.create(PROJECT_URL_PREFIX + "/");
    private final SchemaTypeLoader _s4sloader = XmlBeans.typeLoaderForClassLoader(SchemaDocument.class.getClassLoader());


    private static Set<String> buildDefaultMdefNamespaces() {
        // namespaces which are known to appear in WSDLs redundantly
        return new HashSet<>(
            Collections.singletonList("http://www.openuri.org/2002/04/soap/conversation/"));
    }

    /**
     * Only constructed via StscState.start().
     */
    private StscState() {
    }

    /**
     * Initializer for incremental compilation
     */
    public void initFromTypeSystem(SchemaTypeSystemImpl system, Set<String> newNamespaces) {
//         setGivenTypeSystemName(system.getName().substring(14));

        SchemaContainer[] containers = system.containers();
        for (SchemaContainer container : containers) {
            if (!newNamespaces.contains(container.getNamespace())) {
                // Copy data from the given container
                addContainer(container);
            }
        }
    }


    /* CONTAINERS ================================================================*/

    void addNewContainer(String namespace) {
        if (_containers.containsKey(namespace)) {
            return;
        }

        SchemaContainer container = new SchemaContainer(namespace);
        container.setTypeSystem(sts());
        addNamespace(namespace);
        _containers.put(namespace, container);
    }

    private void addContainer(SchemaContainer container) {
        _containers.put(container.getNamespace(), container);
        List redefModelGroups = container.redefinedModelGroups();
        for (int i = 0; i < redefModelGroups.size(); i++) {
            QName name = ((SchemaModelGroup) redefModelGroups.get(i)).getName();
            _redefinedModelGroups.put(name, redefModelGroups.get(i));
        }

        List redefAttrGroups = container.redefinedAttributeGroups();
        for (int i = 0; i < redefAttrGroups.size(); i++) {
            QName name = ((SchemaAttributeGroup) redefAttrGroups.get(i)).getName();
            _redefinedAttributeGroups.put(name, redefAttrGroups.get(i));
        }

        List redefTypes = container.redefinedGlobalTypes();
        for (int i = 0; i < redefTypes.size(); i++) {
            QName name = ((SchemaType) redefTypes.get(i)).getName();
            _redefinedGlobalTypes.put(name, redefTypes.get(i));
        }

        container.globalElements().forEach(g -> _globalElements.put(g.getName(), g));
        container.globalAttributes().forEach(g -> _globalAttributes.put(g.getName(), g));
        container.modelGroups().forEach(g -> _modelGroups.put(g.getName(), g));
        container.attributeGroups().forEach(g -> _attributeGroups.put(g.getName(), g));

        container.globalTypes().forEach(mapTypes(_globalTypes, false));
        container.documentTypes().forEach(mapTypes(_documentTypes, true));
        container.attributeTypes().forEach(mapTypes(_attributeTypes, true));

        container.identityConstraints().forEach(g -> _idConstraints.put(g.getName(), g));

        _annotations.addAll(container.annotations());
        _namespaces.add(container.getNamespace());
        container.unsetImmutable();
    }

    private Consumer<SchemaType> mapTypes(Map<QName, SchemaType> map, boolean useProperties) {
        return (t) -> {
            QName name = useProperties ? t.getProperties()[0].getName() : t.getName();
            map.put(name, t);
            if (t.getFullJavaName() != null) {
                addClassname(t.getFullJavaName(), t);
            }
        };
    }

    SchemaContainer getContainer(String namespace) {
        return _containers.get(namespace);
    }

    Map<String, SchemaContainer> getContainerMap() {
        return Collections.unmodifiableMap(_containers);
    }

    /* DEPENDENCIES ================================================================*/

    void registerDependency(String sourceNs, String targetNs) {
        _dependencies.registerDependency(sourceNs, targetNs);
    }

    void registerContribution(String ns, String fileUrl) {
        _dependencies.registerContribution(ns, fileUrl);
    }

    SchemaDependencies getDependencies() {
        return _dependencies;
    }

    void setDependencies(SchemaDependencies deps) {
        _dependencies = deps;
    }

    boolean isFileProcessed(String url) {
        return _dependencies.isFileRepresented(url);
    }


    /**
     * Initializer for schematypepath
     */
    public void setImportingTypeLoader(SchemaTypeLoader loader) {
        _importingLoader = loader;
    }

    /**
     * Initializer for error handling.
     */
    public void setErrorListener(Collection<XmlError> errorListener) {
        _errorListener = errorListener;
    }

    /**
     * Passes an error on to the current error listener.
     * KHK: remove this
     */
    public void error(String message, int code, XmlObject loc) {
        addError(_errorListener, message, code, loc);
    }

    /**
     * Passes an error on to the current error listener.
     */
    public void error(String code, Object[] args, XmlObject loc) {
        addError(_errorListener, code, args, loc);
    }

    /**
     * Passes a recovered error on to the current error listener.
     */
    public void recover(String code, Object[] args, XmlObject loc) {
        addError(_errorListener, code, args, loc);
        _recoveredErrors++;
    }

    /**
     * Passes an error on to the current error listener.
     */
    public void warning(String message, int code, XmlObject loc) {
        addWarning(_errorListener, message, code, loc);
    }

    /**
     * Passes an error on to the current error listener.
     */
    public void warning(String code, Object[] args, XmlObject loc) {
        // it's OK for XMLSchema.xsd itself to have reserved type names
        if (code == XmlErrorCodes.RESERVED_TYPE_NAME &&
            loc.documentProperties().getSourceName() != null &&
            loc.documentProperties().getSourceName().indexOf("XMLSchema.xsd") > 0) {
            return;
        }

        addWarning(_errorListener, code, args, loc);
    }

    /**
     * Passes a warning on to the current error listener.
     */
    public void info(String message) {
        addInfo(_errorListener, message);
    }

    /**
     * Passes a warning on to the current error listener.
     */
    public void info(String code, Object[] args) {
        addInfo(_errorListener, code, args);
    }

    // KHK: remove this
    public static void addError(Collection<XmlError> errorListener, String message, int code, XmlObject location) {
        XmlError err =
            XmlError.forObject(
                message,
                XmlError.SEVERITY_ERROR,
                location);
        errorListener.add(err);
    }

    public static void addError(Collection<XmlError> errorListener, String code, Object[] args, XmlObject location) {
        XmlError err =
            XmlError.forObject(
                code,
                args,
                XmlError.SEVERITY_ERROR,
                location);
        errorListener.add(err);
    }

    public static void addError(Collection<XmlError> errorListener, String code, Object[] args, File location) {
        XmlError err =
            XmlError.forLocation(
                code,
                args,
                XmlError.SEVERITY_ERROR,
                location.toURI().toString(), 0, 0, 0);
        errorListener.add(err);
    }

    public static void addError(Collection<XmlError> errorListener, String code, Object[] args, URL location) {
        XmlError err =
            XmlError.forLocation(
                code,
                args,
                XmlError.SEVERITY_ERROR,
                location.toString(), 0, 0, 0);
        errorListener.add(err);
    }

    // KHK: remove this
    public static void addWarning(Collection<XmlError> errorListener, String message, int code, XmlObject location) {
        XmlError err =
            XmlError.forObject(
                message,
                XmlError.SEVERITY_WARNING,
                location);
        errorListener.add(err);
    }

    public static void addWarning(Collection<XmlError> errorListener, String code, Object[] args, XmlObject location) {
        XmlError err =
            XmlError.forObject(
                code,
                args,
                XmlError.SEVERITY_WARNING,
                location);
        errorListener.add(err);
    }

    public static void addInfo(Collection<XmlError> errorListener, String message) {
        XmlError err = XmlError.forMessage(message, XmlError.SEVERITY_INFO);
        errorListener.add(err);
    }

    public static void addInfo(Collection<XmlError> errorListener, String code, Object[] args) {
        XmlError err = XmlError.forMessage(code, args, XmlError.SEVERITY_INFO);
        errorListener.add(err);
    }

    public void setGivenTypeSystemName(String name) {
        _givenStsName = name;
    }

    /**
     * Initializer for references to the SchemaTypeLoader
     */
    public void setTargetSchemaTypeSystem(SchemaTypeSystemImpl target) {
        _target = target;
    }

    /**
     * Accumulates a schema digest...
     */
    public void addSchemaDigest(byte[] digest) {
        if (_noDigest) {
            return;
        }

        if (digest == null) {
            _noDigest = true;
            _digest = null;
            return;
        }

        if (_digest == null) {
            _digest = new byte[128 / 8]; // 128 bits.
        }
        int len = _digest.length;
        if (digest.length < len) {
            len = digest.length;
        }
        for (int i = 0; i < len; i++) {
            _digest[i] ^= digest[i];
        }
    }

    /**
     * The SchemaTypeSystem which we're building types on behalf of.
     */
    public SchemaTypeSystemImpl sts() {
        if (_target != null) {
            return _target;
        }

        String name = _givenStsName;
        if (name == null && _digest != null) {
            name = "s" + new String(HexBin.encode(_digest), StandardCharsets.ISO_8859_1);
        }

        _target = new SchemaTypeSystemImpl(name);
        return _target;
    }

    /**
     * True if the given URI is a local file
     */
    public boolean shouldDownloadURI(String uriString) {
        if (_doingDownloads) {
            return true;
        }

        if (uriString == null) {
            return false;
        }

        try {
            URI uri = new URI(uriString);
            if (uri.getScheme().equalsIgnoreCase("jar") ||
                uri.getScheme().equalsIgnoreCase("zip")) {
                // It may be local or not, depending on the embedded URI
                String s = uri.getSchemeSpecificPart();
                int i = s.lastIndexOf('!');
                return shouldDownloadURI(i > 0 ? s.substring(0, i) : s);
            }
            return uri.getScheme().equalsIgnoreCase("file");
        } catch (Exception e) {
            return false;
        }
    }

    /**
     * Initializer for compatMap.
     */
    public void setOptions(XmlOptions options) {
        if (options == null) {
            return; // defaults are all false.
        }

        _allowPartial = options.hasOption("COMPILE_PARTIAL_TYPESYSTEM");

        _compatMap = (Map) options.get(XmlOptions.COMPILE_SUBSTITUTE_NAMES);
        _noUpa = options.hasOption(XmlOptions.COMPILE_NO_UPA_RULE) ? true :
            !"true".equals(SystemProperties.getProperty("xmlbean.uniqueparticleattribution", "true"));
        _noPvr = options.hasOption(XmlOptions.COMPILE_NO_PVR_RULE) ? true :
            !"true".equals(SystemProperties.getProperty("xmlbean.particlerestriction", "true"));
        _noAnn = options.hasOption(XmlOptions.COMPILE_NO_ANNOTATIONS) ? true :
            !"true".equals(SystemProperties.getProperty("xmlbean.schemaannotations", "true"));
        _doingDownloads = options.hasOption(XmlOptions.COMPILE_DOWNLOAD_URLS) ? true :
            "true".equals(SystemProperties.getProperty("xmlbean.downloadurls", "false"));
        _entityResolver = (EntityResolver) options.get(XmlOptions.ENTITY_RESOLVER);

        if (_entityResolver == null) {
            _entityResolver = ResolverUtil.getGlobalEntityResolver();
        }

        if (_entityResolver != null) {
            _doingDownloads = true;
        }

        if (options.hasOption(XmlOptions.COMPILE_MDEF_NAMESPACES)) {
            _mdefNamespaces.addAll((Collection) options.get(XmlOptions.COMPILE_MDEF_NAMESPACES));

            String local = "##local";
            String any = "##any";

            if (_mdefNamespaces.contains(local)) {
                _mdefNamespaces.remove(local);
                _mdefNamespaces.add("");
            }
            if (_mdefNamespaces.contains(any)) {
                _mdefNamespaces.remove(any);
                _mdefAll = true;
            }
        }
    }

    /**
     * May return null if there is no custom entity resolver.
     */
    public EntityResolver getEntityResolver() {
        return _entityResolver;
    }

    /**
     * True if no unique particle attribution option is set
     */
    public boolean noUpa() {
        return _noUpa;
    }

    /**
     * True if no particle valid (restriciton) option is set
     */
    public boolean noPvr() {
        return _noPvr;
    }

    /**
     * True if annotations should be skipped
     */
    public boolean noAnn() {
        return _noAnn;
    }

    /**
     * True if a partial SchemaTypeSystem should be produced
     */
    // EXPERIMENTAL
    public boolean allowPartial() {
        return _allowPartial;
    }

    /**
     * Get count of recovered errors. Not for public.
     */
    // EXPERIMENTAL
    public int getRecovered() {
        return _recoveredErrors;
    }

    /**
     * Intercepts XML names and translates them
     * through the compat map, if any.
     * <p>
     * Also looks for a default namespace for global definitions.
     */
    private QName compatName(QName name, String chameleonNamespace) {
        // first check for a chameleonNamespace namespace
        if (name.getNamespaceURI().length() == 0 && chameleonNamespace != null && chameleonNamespace.length() > 0) {
            name = new QName(chameleonNamespace, name.getLocalPart());
        }

        if (_compatMap == null) {
            return name;
        }

        QName subst = _compatMap.get(name);
        if (subst == null) {
            return name;
        }
        return subst;
    }

    /**
     * Initializer for the schema config object.
     */
    public void setBindingConfig(BindingConfig config)
        throws IllegalArgumentException {
        _config = config;
    }

    public BindingConfig getBindingConfig()
        throws IllegalArgumentException {
        return _config;
    }

    /**
     * Looks up package override for a namespace URI
     */
    public String getPackageOverride(String namespace) {
        if (_config == null) {
            return null;
        }
        return _config.lookupPackageForNamespace(namespace);
    }

    /**
     * Looks up package override for a namespace URI
     */
    public String getJavaPrefix(String namespace) {
        if (_config == null) {
            return null;
        }
        return _config.lookupPrefixForNamespace(namespace);
    }

    /**
     * Looks up package override for a namespace URI
     */
    public String getJavaSuffix(String namespace) {
        if (_config == null) {
            return null;
        }
        return _config.lookupSuffixForNamespace(namespace);
    }

    /**
     * Looks up configured java name for the given qname.
     */
    public String getJavaname(QName qname, int kind) {
        if (_config == null) {
            return null;
        }
        return _config.lookupJavanameForQName(qname, kind);
    }

    /* SPELLINGS ======================================================*/

    private static String crunchName(QName name) {
        // lowercase, and drop namespace.
        return name.getLocalPart().toLowerCase();
    }

    void addSpelling(QName name, SchemaComponent comp) {
        _misspelledNames.put(crunchName(name), comp);
    }

    SchemaComponent findSpelling(QName name) {
        return _misspelledNames.get(crunchName(name));
    }

    /* NAMESPACES ======================================================*/

    void addNamespace(String targetNamespace) {
        _namespaces.add(targetNamespace);
    }

    String[] getNamespaces() {
        return _namespaces.toArray(new String[0]);
    }

    boolean linkerDefinesNamespace(String namespace) {
        return _importingLoader.isNamespaceDefined(namespace);
    }

    /* TYPES ==========================================================*/

    SchemaTypeImpl findGlobalType(QName name, String chameleonNamespace, String sourceNamespace) {
        name = compatName(name, chameleonNamespace);
        SchemaTypeImpl result = (SchemaTypeImpl) _globalTypes.get(name);
        boolean foundOnLoader = false;
        if (result == null) {
            result = (SchemaTypeImpl) _importingLoader.findType(name);
            foundOnLoader = result != null;
        }
        if (!foundOnLoader && sourceNamespace != null) {
            registerDependency(sourceNamespace, name.getNamespaceURI());
        }
        return result;
    }

    SchemaTypeImpl findRedefinedGlobalType(QName name, String chameleonNamespace, SchemaTypeImpl redefinedBy) {
        QName redefinedName = redefinedBy.getName();
        name = compatName(name, chameleonNamespace);
        if (name.equals(redefinedName)) {
            return (SchemaTypeImpl) _redefinedGlobalTypes.get(redefinedBy);
            // BUGBUG: should also link against _importingLoader.findRedefinedType
        }
        SchemaTypeImpl result = (SchemaTypeImpl) _globalTypes.get(name);
        if (result == null) {
            result = (SchemaTypeImpl) _importingLoader.findType(name);
        }
        // no dependency is needed here, necause it's intra-namespace
        return result;
    }

    void addGlobalType(SchemaTypeImpl type, SchemaTypeImpl redefined) {
        if (type != null) {
            QName name = type.getName();
            SchemaContainer container = getContainer(name.getNamespaceURI());
            assert container != null && container == type.getContainer();

            if (redefined != null) {
                if (_redefinedGlobalTypes.containsKey(redefined)) {
                    if (!ignoreMdef(name)) {
                        if (_mdefAll) {
                            warning(XmlErrorCodes.SCHEMA_PROPERTIES$DUPLICATE,
                                new Object[]{"global type", QNameHelper.pretty(name), ((SchemaType) _redefinedGlobalTypes.get(redefined)).getSourceName()},
                                type.getParseObject());
                        } else {
                            error(XmlErrorCodes.SCHEMA_PROPERTIES$DUPLICATE,
                                new Object[]{"global type", QNameHelper.pretty(name), ((SchemaType) _redefinedGlobalTypes.get(redefined)).getSourceName()},
                                type.getParseObject());
                        }
                    }
                } else {
                    _redefinedGlobalTypes.put(redefined, type);
                    container.addRedefinedType(type.getRef());
                }
            } else {
                if (_globalTypes.containsKey(name)) {
                    if (!ignoreMdef(name)) {
                        if (_mdefAll) {
                            warning(XmlErrorCodes.SCHEMA_PROPERTIES$DUPLICATE,
                                new Object[]{"global type", QNameHelper.pretty(name), _globalTypes.get(name).getSourceName()},
                                type.getParseObject());
                        } else {
                            error(XmlErrorCodes.SCHEMA_PROPERTIES$DUPLICATE,
                                new Object[]{"global type", QNameHelper.pretty(name), _globalTypes.get(name).getSourceName()},
                                type.getParseObject());
                        }
                    }
                } else {
                    _globalTypes.put(name, type);
                    container.addGlobalType(type.getRef());
                    addSpelling(name, type);
                }
            }
        }
    }

    private boolean ignoreMdef(QName name) {
        return _mdefNamespaces.contains(name.getNamespaceURI());
    }

    SchemaType[] globalTypes() {
        return _globalTypes.values().toArray(new SchemaType[0]);
    }

    SchemaType[] redefinedGlobalTypes() {
        return (SchemaType[]) _redefinedGlobalTypes.values().toArray(new SchemaType[0]);
    }

    /* DOCUMENT TYPES =================================================*/

    SchemaTypeImpl findDocumentType(QName name, String chameleonNamespace, String sourceNamespace) {
        name = compatName(name, chameleonNamespace);
        SchemaTypeImpl result = (SchemaTypeImpl) _documentTypes.get(name);
        boolean foundOnLoader = false;
        if (result == null) {
            result = (SchemaTypeImpl) _importingLoader.findDocumentType(name);
            foundOnLoader = result != null;
        }
        if (!foundOnLoader && sourceNamespace != null) {
            registerDependency(sourceNamespace, name.getNamespaceURI());
        }
        return result;
    }

    void addDocumentType(SchemaTypeImpl type, QName name) {
        if (_documentTypes.containsKey(name)) {
            if (!ignoreMdef(name)) {
                if (_mdefAll) {
                    warning(XmlErrorCodes.SCHEMA_PROPERTIES$DUPLICATE,
                        new Object[]{"global element", QNameHelper.pretty(name), _documentTypes.get(name).getSourceName()},
                        type.getParseObject());
                } else {
                    error(XmlErrorCodes.SCHEMA_PROPERTIES$DUPLICATE,
                        new Object[]{"global element", QNameHelper.pretty(name), _documentTypes.get(name).getSourceName()},
                        type.getParseObject());
                }
            }
        } else {
            _documentTypes.put(name, type);
            SchemaContainer container = getContainer(name.getNamespaceURI());
            assert container != null && container == type.getContainer();
            container.addDocumentType(type.getRef());
        }
    }

    SchemaType[] documentTypes() {
        return _documentTypes.values().toArray(new SchemaType[0]);
    }

    /* ATTRIBUTE TYPES =================================================*/

    SchemaTypeImpl findAttributeType(QName name, String chameleonNamespace, String sourceNamespace) {
        name = compatName(name, chameleonNamespace);
        SchemaTypeImpl result = (SchemaTypeImpl) _attributeTypes.get(name);
        boolean foundOnLoader = false;
        if (result == null) {
            result = (SchemaTypeImpl) _importingLoader.findAttributeType(name);
            foundOnLoader = result != null;
        }
        if (!foundOnLoader && sourceNamespace != null) {
            registerDependency(sourceNamespace, name.getNamespaceURI());
        }
        return result;
    }

    void addAttributeType(SchemaTypeImpl type, QName name) {
        if (_attributeTypes.containsKey(name)) {
            if (!ignoreMdef(name)) {
                if (_mdefAll) {
                    warning(XmlErrorCodes.SCHEMA_PROPERTIES$DUPLICATE,
                        new Object[]{"global attribute", QNameHelper.pretty(name), _attributeTypes.get(name).getSourceName()},
                        type.getParseObject());
                } else {
                    error(XmlErrorCodes.SCHEMA_PROPERTIES$DUPLICATE,
                        new Object[]{"global attribute", QNameHelper.pretty(name), _attributeTypes.get(name).getSourceName()},
                        type.getParseObject());
                }
            }
        } else {
            _attributeTypes.put(name, type);
            SchemaContainer container = getContainer(name.getNamespaceURI());
            assert container != null && container == type.getContainer();
            container.addAttributeType(type.getRef());
        }
    }

    SchemaType[] attributeTypes() {
        return _attributeTypes.values().toArray(new SchemaType[0]);
    }

    /* ATTRIBUTES =====================================================*/

    SchemaGlobalAttributeImpl findGlobalAttribute(QName name, String chameleonNamespace, String sourceNamespace) {
        name = compatName(name, chameleonNamespace);
        SchemaGlobalAttributeImpl result = (SchemaGlobalAttributeImpl) _globalAttributes.get(name);
        boolean foundOnLoader = false;
        if (result == null) {
            result = (SchemaGlobalAttributeImpl) _importingLoader.findAttribute(name);
            foundOnLoader = result != null;
        }
        if (!foundOnLoader && sourceNamespace != null) {
            registerDependency(sourceNamespace, name.getNamespaceURI());
        }
        return result;
    }

    void addGlobalAttribute(SchemaGlobalAttributeImpl attribute) {
        if (attribute != null) {
            QName name = attribute.getName();
            _globalAttributes.put(name, attribute);
            addSpelling(name, attribute);
            SchemaContainer container = getContainer(name.getNamespaceURI());
            assert container != null && container == attribute.getContainer();
            container.addGlobalAttribute(attribute.getRef());
        }
    }

    SchemaGlobalAttribute[] globalAttributes() {
        return _globalAttributes.values().toArray(new SchemaGlobalAttribute[0]);
    }

    /* ELEMENTS =======================================================*/

    SchemaGlobalElementImpl findGlobalElement(QName name, String chameleonNamespace, String sourceNamespace) {
        name = compatName(name, chameleonNamespace);
        SchemaGlobalElementImpl result = (SchemaGlobalElementImpl) _globalElements.get(name);
        boolean foundOnLoader = false;
        if (result == null) {
            result = (SchemaGlobalElementImpl) _importingLoader.findElement(name);
            foundOnLoader = result != null;
        }
        if (!foundOnLoader && sourceNamespace != null) {
            registerDependency(sourceNamespace, name.getNamespaceURI());
        }
        return result;
    }

    void addGlobalElement(SchemaGlobalElementImpl element) {
        if (element != null) {
            QName name = element.getName();
            _globalElements.put(name, element);
            SchemaContainer container = getContainer(name.getNamespaceURI());
            assert container != null && container == element.getContainer();
            container.addGlobalElement(element.getRef());
            addSpelling(name, element);
        }
    }

    SchemaGlobalElement[] globalElements() {
        return _globalElements.values().toArray(new SchemaGlobalElement[0]);
    }

    /* ATTRIBUTE GROUPS ===============================================*/

    SchemaAttributeGroupImpl findAttributeGroup(QName name, String chameleonNamespace, String sourceNamespace) {
        name = compatName(name, chameleonNamespace);
        SchemaAttributeGroupImpl result = (SchemaAttributeGroupImpl) _attributeGroups.get(name);
        boolean foundOnLoader = false;
        if (result == null) {
            result = (SchemaAttributeGroupImpl) _importingLoader.findAttributeGroup(name);
            foundOnLoader = result != null;
        }
        if (!foundOnLoader && sourceNamespace != null) {
            registerDependency(sourceNamespace, name.getNamespaceURI());
        }
        return result;
    }

    SchemaAttributeGroupImpl findRedefinedAttributeGroup(QName name, String chameleonNamespace, SchemaAttributeGroupImpl redefinedBy) {
        QName redefinitionFor = redefinedBy.getName();
        name = compatName(name, chameleonNamespace);
        if (name.equals(redefinitionFor)) {
            return (SchemaAttributeGroupImpl) _redefinedAttributeGroups.get(redefinedBy);
            // BUGBUG: should also link against _importingLoader.findRedefinedAttributeGroup
        }
        SchemaAttributeGroupImpl result = (SchemaAttributeGroupImpl) _attributeGroups.get(name);
        if (result == null) {
            result = (SchemaAttributeGroupImpl) _importingLoader.findAttributeGroup(name);
        }
        return result;
    }

    void addAttributeGroup(SchemaAttributeGroupImpl attributeGroup, SchemaAttributeGroupImpl redefined) {
        if (attributeGroup != null) {
            QName name = attributeGroup.getName();
            SchemaContainer container = getContainer(name.getNamespaceURI());
            assert container != null && container == attributeGroup.getContainer();
            if (redefined != null) {
                if (_redefinedAttributeGroups.containsKey(redefined)) {
                    if (!ignoreMdef(name)) {
                        if (_mdefAll) {
                            warning(XmlErrorCodes.SCHEMA_PROPERTIES$DUPLICATE,
                                new Object[]{"attribute group", QNameHelper.pretty(name), ((SchemaComponent) _redefinedAttributeGroups.get(redefined)).getSourceName()},
                                attributeGroup.getParseObject());
                        } else {
                            error(XmlErrorCodes.SCHEMA_PROPERTIES$DUPLICATE,
                                new Object[]{"attribute group", QNameHelper.pretty(name), ((SchemaComponent) _redefinedAttributeGroups.get(redefined)).getSourceName()},
                                attributeGroup.getParseObject());
                        }
                    }
                } else {
                    _redefinedAttributeGroups.put(redefined, attributeGroup);
                    container.addRedefinedAttributeGroup(attributeGroup.getRef());
                }
            } else {
                if (_attributeGroups.containsKey(name)) {
                    if (!ignoreMdef(name)) {
                        if (_mdefAll) {
                            warning(XmlErrorCodes.SCHEMA_PROPERTIES$DUPLICATE,
                                new Object[]{"attribute group", QNameHelper.pretty(name), _attributeGroups.get(name).getSourceName()},
                                attributeGroup.getParseObject());
                        } else {
                            error(XmlErrorCodes.SCHEMA_PROPERTIES$DUPLICATE,
                                new Object[]{"attribute group", QNameHelper.pretty(name), _attributeGroups.get(name).getSourceName()},
                                attributeGroup.getParseObject());
                        }
                    }
                } else {
                    _attributeGroups.put(attributeGroup.getName(), attributeGroup);
                    addSpelling(attributeGroup.getName(), attributeGroup);
                    container.addAttributeGroup(attributeGroup.getRef());
                }
            }
        }
    }

    SchemaAttributeGroup[] attributeGroups() {
        return _attributeGroups.values().toArray(new SchemaAttributeGroup[0]);
    }

    SchemaAttributeGroup[] redefinedAttributeGroups() {
        return (SchemaAttributeGroup[]) _redefinedAttributeGroups.values().toArray(new SchemaAttributeGroup[0]);
    }

    /* MODEL GROUPS ===================================================*/

    SchemaModelGroupImpl findModelGroup(QName name, String chameleonNamespace, String sourceNamespace) {
        name = compatName(name, chameleonNamespace);
        SchemaModelGroupImpl result = (SchemaModelGroupImpl) _modelGroups.get(name);
        boolean foundOnLoader = false;
        if (result == null) {
            result = (SchemaModelGroupImpl) _importingLoader.findModelGroup(name);
            foundOnLoader = result != null;
        }
        if (!foundOnLoader && sourceNamespace != null) {
            registerDependency(sourceNamespace, name.getNamespaceURI());
        }
        return result;
    }

    SchemaModelGroupImpl findRedefinedModelGroup(QName name, String chameleonNamespace, SchemaModelGroupImpl redefinedBy) {
        QName redefinitionFor = redefinedBy.getName();
        name = compatName(name, chameleonNamespace);
        if (name.equals(redefinitionFor)) {
            return (SchemaModelGroupImpl) _redefinedModelGroups.get(redefinedBy);
            // BUGBUG: should also link against _importingLoader.findRedefinedModelGroup
        }
        SchemaModelGroupImpl result = (SchemaModelGroupImpl) _modelGroups.get(name);
        if (result == null) {
            result = (SchemaModelGroupImpl) _importingLoader.findModelGroup(name);
        }
        return result;
    }

    void addModelGroup(SchemaModelGroupImpl modelGroup, SchemaModelGroupImpl redefined) {
        if (modelGroup != null) {
            QName name = modelGroup.getName();
            SchemaContainer container = getContainer(name.getNamespaceURI());
            assert container != null && container == modelGroup.getContainer();
            if (redefined != null) {
                if (_redefinedModelGroups.containsKey(redefined)) {
                    if (!ignoreMdef(name)) {
                        if (_mdefAll) {
                            warning(XmlErrorCodes.SCHEMA_PROPERTIES$DUPLICATE,
                                new Object[]{"model group", QNameHelper.pretty(name), ((SchemaComponent) _redefinedModelGroups.get(redefined)).getSourceName()},
                                modelGroup.getParseObject());
                        } else {
                            error(XmlErrorCodes.SCHEMA_PROPERTIES$DUPLICATE,
                                new Object[]{"model group", QNameHelper.pretty(name), ((SchemaComponent) _redefinedModelGroups.get(redefined)).getSourceName()},
                                modelGroup.getParseObject());
                        }
                    }
                } else {
                    _redefinedModelGroups.put(redefined, modelGroup);
                    container.addRedefinedModelGroup(modelGroup.getRef());
                }
            } else {
                if (_modelGroups.containsKey(name)) {
                    if (!ignoreMdef(name)) {
                        if (_mdefAll) {
                            warning(XmlErrorCodes.SCHEMA_PROPERTIES$DUPLICATE,
                                new Object[]{"model group", QNameHelper.pretty(name), _modelGroups.get(name).getSourceName()},
                                modelGroup.getParseObject());
                        } else {
                            error(XmlErrorCodes.SCHEMA_PROPERTIES$DUPLICATE,
                                new Object[]{"model group", QNameHelper.pretty(name), _modelGroups.get(name).getSourceName()},
                                modelGroup.getParseObject());
                        }
                    }
                } else {
                    _modelGroups.put(modelGroup.getName(), modelGroup);
                    addSpelling(modelGroup.getName(), modelGroup);
                    container.addModelGroup(modelGroup.getRef());
                }
            }
        }
    }

    SchemaModelGroup[] modelGroups() {
        return _modelGroups.values().toArray(new SchemaModelGroup[0]);
    }

    SchemaModelGroup[] redefinedModelGroups() {
        return (SchemaModelGroup[]) _redefinedModelGroups.values().toArray(new SchemaModelGroup[0]);
    }

    /* IDENTITY CONSTRAINTS ===========================================*/

    SchemaIdentityConstraintImpl findIdConstraint(QName name, String chameleonNamespace, String sourceNamespace) {
        name = compatName(name, chameleonNamespace);
        if (sourceNamespace != null) {
            registerDependency(sourceNamespace, name.getNamespaceURI());
        }
        return (SchemaIdentityConstraintImpl) _idConstraints.get(name);
    }

    void addIdConstraint(SchemaIdentityConstraintImpl idc) {
        if (idc != null) {
            QName name = idc.getName();
            SchemaContainer container = getContainer(name.getNamespaceURI());
            assert container != null && container == idc.getContainer();
            if (_idConstraints.containsKey(name)) {
                if (!ignoreMdef(name)) {
                    warning(XmlErrorCodes.SCHEMA_PROPERTIES$DUPLICATE,
                        new Object[]{"identity constraint", QNameHelper.pretty(name), _idConstraints.get(name).getSourceName()},
                        idc.getParseObject());
                }
            } else {
                _idConstraints.put(name, idc);
                addSpelling(idc.getName(), idc);
                container.addIdentityConstraint(idc.getRef());
            }
        }
    }

    SchemaIdentityConstraintImpl[] idConstraints() {
        return _idConstraints.values().toArray(new SchemaIdentityConstraintImpl[0]);
    }

    /* ANNOTATIONS ===========================================*/

    void addAnnotation(SchemaAnnotationImpl ann, String targetNamespace) {
        if (ann != null) {
            SchemaContainer container = getContainer(targetNamespace);
            assert container != null && container == ann.getContainer();
            _annotations.add(ann);
            container.addAnnotation(ann);
        }
    }

    List<SchemaAnnotation> annotations() {
        return _annotations;
    }

    /* RECURSION AVOIDANCE ============================================*/
    boolean isProcessing(SchemaComponent obj) {
        return _processingGroups.contains(obj);
    }

    void startProcessing(SchemaComponent obj) {
        assert (!_processingGroups.contains(obj));
        _processingGroups.add(obj);
    }

    void finishProcessing(SchemaComponent obj) {
        assert (_processingGroups.contains(obj));
        _processingGroups.remove(obj);
    }

    SchemaComponent[] getCurrentProcessing() {
        return _processingGroups.toArray(new SchemaComponent[0]);
    }

    /* JAVAIZATION ====================================================*/

    Map<String, SchemaType> typesByClassname() {
        return Collections.unmodifiableMap(_typesByClassname);
    }

    void addClassname(String classname, SchemaType type) {
        _typesByClassname.put(classname, type);
    }


    /**
     * Stack management if (heaven help us) we ever need to do
     * nested compilation of schema type system.
     */
    private static final class StscStack {
        StscState current;
        List<StscState> stack = new ArrayList<>();

        final StscState push() {
            stack.add(current);
            current = new StscState();
            return current;
        }

        final void pop() {
            current = stack.get(stack.size() - 1);
            stack.remove(stack.size() - 1);
        }
    }

    public static void clearThreadLocals() {
        tl_stscStack.remove();
    }

    public static StscState start() {
        StscStack stscStack = tl_stscStack.get();

        if (stscStack == null) {
            stscStack = new StscStack();
            tl_stscStack.set(stscStack);
        }
        return stscStack.push();
    }

    public static StscState get() {
        return tl_stscStack.get().current;
    }

    public static void end() {
        StscStack stscStack = tl_stscStack.get();
        stscStack.pop();
        if (stscStack.stack.size() == 0) {
            tl_stscStack.set(null);            // this is required to release all the references in this classloader
        }
        // which will enable class unloading and avoid OOM in PermGen
    }


    static XmlValueRef build_wsstring(int wsr) {
        switch (wsr) {
            case SchemaType.WS_PRESERVE:
                return XMLSTR_PRESERVE;
            case SchemaType.WS_REPLACE:
                return XMLSTR_REPLACE;
            case SchemaType.WS_COLLAPSE:
                return XMLSTR_COLLAPSE;
        }
        return null;
    }

    static XmlValueRef buildString(String str) {
        if (str == null) {
            return null;
        }

        try {
            XmlStringImpl i = new XmlStringImpl();
            i.set(str);
            i.setImmutable();
            return new XmlValueRef(i);
        } catch (XmlValueOutOfRangeException e) {
            return null;
        }
    }

    public void notFoundError(QName itemName, int code, XmlObject loc, boolean recovered) {
        String expected;
        String expectedName = QNameHelper.pretty(itemName);
        String found = null;
        String foundName = null;
        String sourceName = null;

        if (recovered) {
            _recoveredErrors++;
        }

        switch (code) {
            case SchemaType.TYPE:
                expected = "type";
                break;
            case SchemaType.ELEMENT:
                expected = "element";
                break;
            case SchemaType.ATTRIBUTE:
                expected = "attribute";
                break;
            case SchemaType.MODEL_GROUP:
                expected = "model group";
                break;
            case SchemaType.ATTRIBUTE_GROUP:
                expected = "attribute group";
                break;
            case SchemaType.IDENTITY_CONSTRAINT:
                expected = "identity constraint";
                break;
            default:
                assert (false);
                expected = "definition";
                break;
        }

        SchemaComponent foundComponent = findSpelling(itemName);
        QName name;
        if (foundComponent != null) {
            name = foundComponent.getName();
            if (name != null) {
                switch (foundComponent.getComponentType()) {
                    case SchemaComponent.TYPE:
                        found = "type";
                        sourceName = foundComponent.getSourceName();
                        break;
                    case SchemaComponent.ELEMENT:
                        found = "element";
                        sourceName = foundComponent.getSourceName();
                        break;
                    case SchemaComponent.ATTRIBUTE:
                        found = "attribute";
                        sourceName = foundComponent.getSourceName();
                        break;
                    case SchemaComponent.ATTRIBUTE_GROUP:
                        found = "attribute group";
                        break;
                    case SchemaComponent.MODEL_GROUP:
                        found = "model group";
                        break;
                }

                if (sourceName != null) {
                    sourceName = sourceName.substring(sourceName.lastIndexOf('/') + 1);
                }

                if (!name.equals(itemName)) {
                    foundName = QNameHelper.pretty(name);
                }
            }
        }

        if (found == null) {
            // error with no help
            error(XmlErrorCodes.SCHEMA_QNAME_RESOLVE,
                new Object[]{expected, expectedName}, loc);
        } else {
            // error with help
            error(XmlErrorCodes.SCHEMA_QNAME_RESOLVE$HELP,
                new Object[]{
                    expected,
                    expectedName,
                    found,
                    (foundName == null ? new Integer(0) : new Integer(1)),
                    foundName,
                    (sourceName == null ? new Integer(0) : new Integer(1)),
                    sourceName
                },
                loc);
        }
    }


    /**
     * Produces the "sourceName" (to be used within the schema project
     * source file copies) from the URI of the original source.
     * <p>
     * Returns null if none.
     */
    public String sourceNameForUri(String uri) {
        return _sourceForUri.get(uri);
    }

    /**
     * Returns the whole sourceCopyMap, mapping URI's that have
     * been read to "sourceName" local names that have been used
     * to tag the types.
     */
    public Map<String, String> sourceCopyMap() {
        return Collections.unmodifiableMap(_sourceForUri);
    }

    /**
     * The base URI to use for nice filenames when saving sources.
     */
    public void setBaseUri(URI uri) {
        _baseURI = uri;
    }

    public String relativize(String uri) {
        return relativize(uri, false);
    }

    public String computeSavedFilename(String uri) {
        return relativize(uri, true);
    }

    private String relativize(String uri, boolean forSavedFilename) {
        if (uri == null) {
            return null;
        }

        // deal with things that do not look like absolute uris
        if (uri.startsWith("/")) {
            uri = PROJECT_URL_PREFIX + uri.replace('\\', '/');
        } else {
            // looks like a URL?
            int colon = uri.indexOf(':');
            if (colon <= 1 || !uri.substring(0, colon).matches("^\\w+$")) {
                uri = PROJECT_URL_PREFIX + "/" + uri.replace('\\', '/');
            }
        }

        // now relativize against that...
        if (_baseURI != null) {
            try {
                URI relative = _baseURI.relativize(new URI(uri));
                if (!relative.isAbsolute()) {
                    return relative.toString();
                } else {
                    uri = relative.toString();
                }
            } catch (URISyntaxException e) {
            }
        }

        if (!forSavedFilename) {
            return uri;
        }

        int lastslash = uri.lastIndexOf('/');
        String dir = QNameHelper.hexsafe(lastslash == -1 ? "" : uri.substring(0, lastslash));

        int question = uri.indexOf('?', lastslash + 1);
        if (question == -1) {
            return dir + "/" + uri.substring(lastslash + 1);
        }

        String query = QNameHelper.hexsafe(uri.substring(question));

        // if encoded query part is longer than 64 characters, just drop it
        if (query.startsWith(QNameHelper.URI_SHA1_PREFIX)) {
            return dir + "/" + uri.substring(lastslash + 1, question);
        } else {
            return dir + "/" + uri.substring(lastslash + 1, question) + query;
        }
    }

    /**
     * Notes another URI that has been consumed during compilation
     * (this is the URI that is in the document .NAME property)
     */
    public void addSourceUri(String uri, String nameToUse) {
        if (uri == null) {
            return;
        }

        if (nameToUse == null) {
            nameToUse = computeSavedFilename(uri);
        }

        _sourceForUri.put(uri, nameToUse);
    }

    /**
     * Returns the error listener being filled in during this compilation
     */
    public Collection<XmlError> getErrorListener() {
        return _errorListener;
    }

    /**
     * Returns the schema type loader to use for processing s4s
     */
    public SchemaTypeLoader getS4SLoader() {
        return _s4sloader;
    }

    public File getSchemasDir() {
        return _schemasDir;
    }

    public void setSchemasDir(File _schemasDir) {
        this._schemasDir = _schemasDir;
    }
}
