/*
* 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.jackrabbit.oak.plugins.name;

import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;

import org.apache.jackrabbit.oak.api.PropertyState;
import org.apache.jackrabbit.oak.api.Tree;
import org.apache.jackrabbit.oak.api.Type;
import org.apache.jackrabbit.oak.spi.namespace.NamespaceConstants;
import org.apache.jackrabbit.oak.spi.nodetype.NodeTypeConstants;
import org.apache.jackrabbit.oak.spi.state.NodeBuilder;

import static com.google.common.base.Preconditions.checkState;
import static com.google.common.collect.Maps.newConcurrentMap;
import static com.google.common.collect.Maps.newHashMap;
import static com.google.common.collect.Sets.newHashSet;
import static javax.jcr.NamespaceRegistry.NAMESPACE_JCR;
import static javax.jcr.NamespaceRegistry.NAMESPACE_MIX;
import static javax.jcr.NamespaceRegistry.NAMESPACE_NT;
import static javax.jcr.NamespaceRegistry.NAMESPACE_XML;
import static javax.jcr.NamespaceRegistry.PREFIX_JCR;
import static javax.jcr.NamespaceRegistry.PREFIX_MIX;
import static javax.jcr.NamespaceRegistry.PREFIX_NT;
import static javax.jcr.NamespaceRegistry.PREFIX_XML;
import static org.apache.jackrabbit.JcrConstants.JCR_PRIMARYTYPE;
import static org.apache.jackrabbit.JcrConstants.JCR_SYSTEM;
import static org.apache.jackrabbit.oak.api.Type.NAME;
import static org.apache.jackrabbit.oak.api.Type.STRING;
import static org.apache.jackrabbit.util.Text.escapeIllegalJcrChars;

/**
 * Internal static utility class for managing the persisted namespace registry.
 */
public class Namespaces implements NamespaceConstants {

    /**
     * Global cache of encoded URIs.
     */
    private static final Map<String, String> ENCODED_URIS = newConcurrentMap();

    /**
     * By default, item names with non space whitespace chars are not allowed.
     * However initial Oak release did allowed that and this flag is provided
     * to revert back to old behaviour if required for some case temporarily
     */
    private static final boolean allowOtherWhitespaceChars = Boolean.getBoolean("oak.allowOtherWhitespaceChars");

    /**
     * By default, item names with control characters are not allowed.
     * Oak releases prior to 1.10 allowed these (in conflict with the JCR
     * specification), so if required the check can be turned off.
     * See OAK-7208.
     */
    private static final boolean allowOtherControlChars = Boolean.getBoolean("oak.allowOtherControlChars");

    /**
     * By default, item names with non-ASCII whitespace characters are allowed.
     * Oak releases prior to 1.10 disallowed these, so if required the check can
     * be turned on again. See OAK-4857.
     */
    private static final boolean disallowNonASCIIWhitespaceChars = Boolean.getBoolean("oak.disallowNonASCIIWhitespaceChars");

    private Namespaces() {
    }

    public static void setupNamespaces(NodeBuilder system) {
        if (!system.hasChildNode(REP_NAMESPACES)) {
            NodeBuilder namespaces = createStandardMappings(system);
            buildIndexNode(namespaces); // index node for faster lookup
        }
    }

    public static NodeBuilder createStandardMappings(NodeBuilder system) {
        checkState(!system.hasChildNode(REP_NAMESPACES));

        NodeBuilder namespaces = system.setChildNode(REP_NAMESPACES);
        namespaces.setProperty(JCR_PRIMARYTYPE, NodeTypeConstants.NT_REP_UNSTRUCTURED, NAME);

        // Standard namespace specified by JCR (default one not included)
        namespaces.setProperty(PREFIX_JCR, NAMESPACE_JCR);
        namespaces.setProperty(PREFIX_NT,  NAMESPACE_NT);
        namespaces.setProperty(PREFIX_MIX, NAMESPACE_MIX);
        namespaces.setProperty(PREFIX_XML, NAMESPACE_XML);

        // Namespace included in Jackrabbit 2.x
        namespaces.setProperty(PREFIX_SV, NAMESPACE_SV);
        namespaces.setProperty(PREFIX_REP, NAMESPACE_REP);

        // Oak Namespace
        namespaces.setProperty(PREFIX_OAK, NAMESPACE_OAK);

        return namespaces;
    }

    public static String addCustomMapping(
            NodeBuilder namespaces, String uri, String prefixHint) {
        // first look for an existing mapping for the given URI
        for (PropertyState property : namespaces.getProperties()) {
            if (property.getType() == STRING) {
                String prefix = property.getName();
                if (isValidPrefix(prefix)
                        && uri.equals(property.getValue(STRING))) {
                    return prefix;
                }
            }
        }

        // no existing mapping found for the URI, make sure prefix is unique
        String prefix = prefixHint;
        int iteration = 1;
        while (namespaces.hasProperty(prefix)) {
            prefix = prefixHint + ++iteration;
        }

        // add the new mapping with its unique prefix
        namespaces.setProperty(prefix, uri);
        return prefix;
    }

    public static void buildIndexNode(NodeBuilder namespaces) {
        // initialize prefix and URI sets with the defaults namespace
        // that's not stored along with the other mappings
        Set<String> prefixes = newHashSet("");
        Set<String> uris = newHashSet("");
        Map<String, String> nsmap = collectNamespaces(namespaces.getProperties());
        prefixes.addAll(nsmap.keySet());
        uris.addAll(nsmap.values());

        NodeBuilder data = namespaces.setChildNode(REP_NSDATA);
        data.setProperty(JCR_PRIMARYTYPE, NodeTypeConstants.NT_REP_UNSTRUCTURED, Type.NAME);
        data.setProperty(REP_PREFIXES, prefixes, Type.STRINGS);
        data.setProperty(REP_URIS, uris, Type.STRINGS);
        for (Entry<String, String> e : nsmap.entrySet()) {
            // persist as reverse index
            data.setProperty(encodeUri(e.getValue()), e.getKey());
        }
    }

    private static Tree getNamespaceTree(Tree root) {
        return root.getChild(JCR_SYSTEM).getChild(REP_NAMESPACES);
    }

    public static Map<String, String> getNamespaceMap(Tree root) {
        Map<String, String> map = collectNamespaces(getNamespaceTree(root).getProperties());
        map.put("", ""); // default namespace, not included in tree
        return map;
    }

    static Map<String, String> collectNamespaces(Iterable<? extends PropertyState> properties) {
        Map<String, String> map = newHashMap();
        for (PropertyState property : properties) {
            String prefix = property.getName();
            if (STRING.equals(property.getType()) && isValidPrefix(prefix)) {
                map.put(prefix, property.getValue(STRING));
            }
        }
        return map;
    }

    public static String getNamespacePrefix(Tree root, String uri) {
        if (uri.isEmpty()) {
            return uri;
        }

        Tree nsdata = getNamespaceTree(root).getChild(REP_NSDATA);
        PropertyState ps = nsdata.getProperty(encodeUri(uri));
        if (ps != null) {
            return ps.getValue(STRING);
        }

        return null;
    }

    public static String getNamespaceURI(Tree root, String prefix) {
        if (prefix.isEmpty()) {
            return prefix;
        }

        if (isValidPrefix(prefix)) {
            PropertyState property = getNamespaceTree(root).getProperty(prefix);
            if (property != null && property.getType() == STRING) {
                return property.getValue(STRING);
            }
        }

        return null;
    }

    // utils

    /**
     * encodes the uri value to be used as a property
     * 
     * @param uri
     * @return encoded uri
     */
    public static String encodeUri(String uri) {
        String encoded = ENCODED_URIS.get(uri);
        if (encoded == null) {
            encoded =  escapeIllegalJcrChars(uri);
            if (ENCODED_URIS.size() > 1000) {
                ENCODED_URIS.clear(); // prevents DoS attacks
            }
            ENCODED_URIS.put(uri, encoded);
        }
        return encoded;
    }

    // validation

    public static boolean isValidPrefix(String prefix) {
        // TODO: Other prefix rules?
        return prefix.indexOf(':') == -1;
    }

    public static boolean isValidLocalName(String local) {
        if (local.isEmpty() || ".".equals(local) || "..".equals(local)) {
            return false;
        }

        for (int i = 0; i < local.length(); i++) {

            char ch = local.charAt(i);

            boolean spaceChar;
            if (disallowNonASCIIWhitespaceChars) {
                // behavior before OAK-4857 was fixed
                spaceChar = allowOtherWhitespaceChars ? Character.isSpaceChar(ch) : Character.isWhitespace(ch);
            } else {
                // disallow just leading and trailing ' ', plus CR, LF and TAB
                spaceChar = ch == ' ' || ch == 0x9 || ch == 0xa || ch == 0xd;
            }

            if (spaceChar) {
                if (i == 0) {
                    return false; // leading whitespace
                } else if (i == local.length() - 1) {
                    return false; // trailing whitespace
                } else if (ch != ' ') {
                    return false; // only spaces are allowed as whitespace
                }
            } else if ("/:[]|*".indexOf(ch) != -1) { // TODO: XMLChar check for unpaired surrogates
                return false; // invalid name character
            } else if (!allowOtherControlChars && ch >= 0 && ch < 32 && (ch != 9 && ch != 0xa && ch != 0xd)) {
                // https://www.w3.org/TR/xml/#NT-Char - disallowed control chars
                return false;
            }
        }

        // TODO: Other name rules?
        return true;
    }

}
