/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements.  See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You 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.vxquery.context;

import java.util.List;
import java.util.Map;

import javax.xml.namespace.QName;

import org.apache.vxquery.collations.CodepointCollation;
import org.apache.vxquery.collations.Collation;
import org.apache.vxquery.functions.BuiltinFunctions;
import org.apache.vxquery.functions.Function;
import org.apache.vxquery.types.AttributeType;
import org.apache.vxquery.types.BuiltinTypeRegistry;
import org.apache.vxquery.types.ElementType;
import org.apache.vxquery.types.ItemType;
import org.apache.vxquery.types.SchemaType;
import org.apache.vxquery.types.SequenceType;
import org.apache.vxquery.xmlquery.query.XQueryConstants;

public final class RootStaticContextImpl extends StaticContextImpl {
    public static final StaticContext INSTANCE;

    static {
        INSTANCE = new RootStaticContextImpl();

        // Namespaces
        INSTANCE.registerNamespaceUri(XQueryConstants.XML_PREFIX, XQueryConstants.XML_NSURI);
        INSTANCE.registerNamespaceUri(XQueryConstants.XS_PREFIX, XQueryConstants.XS_NSURI);
        INSTANCE.registerNamespaceUri(XQueryConstants.XSEXT_PREFIX, XQueryConstants.XSEXT_NSURI);
        INSTANCE.registerNamespaceUri(XQueryConstants.XSI_PREFIX, XQueryConstants.XSI_NSURI);
        INSTANCE.registerNamespaceUri(XQueryConstants.FN_PREFIX, XQueryConstants.FN_NSURI);
        INSTANCE.registerNamespaceUri(XQueryConstants.LOCAL_PREFIX, XQueryConstants.LOCAL_NSURI);
        INSTANCE.registerNamespaceUri(XQueryConstants.OP_PREFIX, XQueryConstants.OP_NSURI);
        INSTANCE.registerNamespaceUri(XQueryConstants.OPEXT_PREFIX, XQueryConstants.OPEXT_NSURI);
        INSTANCE.registerNamespaceUri(XQueryConstants.JS_PREFIX, XQueryConstants.JS_NSURI);
        INSTANCE.registerNamespaceUri(XQueryConstants.JN_PREFIX, XQueryConstants.JN_NSURI);
        INSTANCE.registerNamespaceUri(XQueryConstants.LIBJN_PREFIX, XQueryConstants.LIBJN_NSURI);
        INSTANCE.registerNamespaceUri(XQueryConstants.JERR_PREFIX, XQueryConstants.JERR_NSURI);
        INSTANCE.registerNamespaceUri(XQueryConstants.JUPD_PREFIX, XQueryConstants.JUPD_NSURI);
        INSTANCE.registerNamespaceUri(XQueryConstants.JDM_PREFIX, XQueryConstants.JDM_NSURI);

        INSTANCE.setBaseUri(".");

        INSTANCE.setDefaultFunctionNamespaceUri(XQueryConstants.FN_NSURI);

        // Types
        for (Map.Entry<QName, SchemaType> e : BuiltinTypeRegistry.TYPE_MAP.entrySet()) {
            QName typeName = e.getKey();
            SchemaType type = e.getValue();
            INSTANCE.registerSchemaType(typeName, type);
        }

        for (Map.Entry<ItemType, SequenceType[]> e : SequenceType.BUILTIN_SEQ_TYPES.entrySet()) {
            for (SequenceType st : e.getValue()) {
                INSTANCE.encodeSequenceType(st);
            }
        }

        // Functions
        for (Function fn : BuiltinFunctions.FUNCTION_COLLECTION) {
            INSTANCE.registerFunction(fn);
        }

        INSTANCE.registerCollation(CodepointCollation.URI, CodepointCollation.INSTANCE);

        INSTANCE.setDefaultCollation(CodepointCollation.URI);

        ((RootStaticContextImpl) INSTANCE).sealed = true;
    }

    private boolean sealed;

    private RootStaticContextImpl() {
        super(null);
    }

    private void checkSealed() {
        if (sealed) {
            throw new IllegalStateException();
        }
    }

    @Override
    public void registerAttributeDeclaration(QName name, AttributeType attrDecl) {
        checkSealed();
        super.registerAttributeDeclaration(name, attrDecl);
    }

    @Override
    public void registerCollation(String collationName, Collation collation) {
        checkSealed();
        super.registerCollation(collationName, collation);
    }

    @Override
    public void registerCollectionType(String collectionUri, SequenceType type) {
        checkSealed();
        super.registerCollectionType(collectionUri, type);
    }

    @Override
    public void registerDocumentType(String docUri, SequenceType type) {
        checkSealed();
        super.registerDocumentType(docUri, type);
    }

    @Override
    public void registerElementDeclaration(QName name, ElementType elemDecl) {
        checkSealed();
        super.registerElementDeclaration(name, elemDecl);
    }

    @Override
    public void registerFunction(Function function) {
        checkSealed();
        super.registerFunction(function);
    }

    @Override
    public void registerNamespaceUri(String prefix, String uri) {
        checkSealed();
        super.registerNamespaceUri(prefix, uri);
    }

    @Override
    public void registerModuleImport(String uri, List<String> locations) {
        checkSealed();
        super.registerModuleImport(uri, locations);
    }

    @Override
    public void registerSchemaImport(String uri, List<String> locations) {
        checkSealed();
        super.registerSchemaImport(uri, locations);
    }

    @Override
    public void registerSchemaType(QName name, SchemaType type) {
        checkSealed();
        super.registerSchemaType(name, type);
    }

    @Override
    public int encodeSequenceType(SequenceType type) {
        checkSealed();
        return super.encodeSequenceType(type);
    }

    @Override
    public void setBaseUri(String baseUri) {
        checkSealed();
        super.setBaseUri(baseUri);
    }

    @Override
    public void setBoundarySpaceProperty(BoundarySpaceProperty boundarySpaceProperty) {
        checkSealed();
        super.setBoundarySpaceProperty(boundarySpaceProperty);
    }

    @Override
    public void setConstructionModeProperty(ConstructionModeProperty constructionMode) {
        checkSealed();
        super.setConstructionModeProperty(constructionMode);
    }

    @Override
    public void setCopyNamespacesModeProperty(CopyNamespacesModeProperty copyNamespacesMode) {
        checkSealed();
        super.setCopyNamespacesModeProperty(copyNamespacesMode);
    }

    @Override
    public void setDefaultCollation(String defaultCollation) {
        checkSealed();
        super.setDefaultCollation(defaultCollation);
    }

    @Override
    public void setDefaultCollectionType(SequenceType type) {
        checkSealed();
        super.setDefaultCollectionType(type);
    }

    @Override
    public void setDefaultElementNamespaceUri(String uri) {
        checkSealed();
        super.setDefaultElementNamespaceUri(uri);
    }

    @Override
    public void setDefaultFunctionNamespaceUri(String uri) {
        checkSealed();
        super.setDefaultFunctionNamespaceUri(uri);
    }

    @Override
    public void setEmptyOrderProperty(EmptyOrderProperty emptyOrder) {
        checkSealed();
        super.setEmptyOrderProperty(emptyOrder);
    }

    @Override
    public void setOrderingModeProperty(OrderingModeProperty orderingMode) {
        checkSealed();
        super.setOrderingModeProperty(orderingMode);
    }

    @Override
    public IStaticContextFactory createFactory() {
        return RootStaticContextFactory.INSTANCE;
    }
}
