/*
 * 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.jcr;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;

import java.util.Map;
import java.util.UUID;

import javax.jcr.ItemExistsException;
import javax.jcr.NamespaceException;
import javax.jcr.Node;
import javax.jcr.PathNotFoundException;
import javax.jcr.Repository;
import javax.jcr.RepositoryException;
import javax.jcr.Session;

import org.apache.jackrabbit.oak.fixture.NodeStoreFixture;
import org.apache.jackrabbit.oak.spi.state.NodeStore;
import org.junit.After;
import org.junit.AfterClass;
import org.junit.Before;
import org.junit.Test;

import com.google.common.collect.Maps;

public class ValidNamesTest extends AbstractRepositoryTest {

    private static final String TEST_NODE = "test_node";
    private static final String TEST_PATH = '/' + TEST_NODE;
    private static final Map<NodeStoreFixture, NodeStore> STORES = Maps.newConcurrentMap();

    private Node testNode;

    private String unmappedNsPrefix;
    private String testPrefix;
    private String testNsUri;

    private static char[] SURROGATE_PAIR = Character.toChars(0x1f4a9);

    public ValidNamesTest(NodeStoreFixture fixture) {
        super(fixture);
    }

    @Before
    public void setup() throws NamespaceException, RepositoryException {
        Repository repo = createRepository(fixture);
        Session session = repo.login(getAdminCredentials());
        Node root = session.getRootNode();
        testNode = root.addNode(TEST_NODE);
        session.save();

        StringBuilder t = new StringBuilder();
        for (String prefix : session.getNamespacePrefixes()) {
            int l = t.length();
            if (prefix.length() > l) {
                t.append((char) (prefix.charAt(l) ^ 1));
            } else {
                t.append('x');
            }
        }
        unmappedNsPrefix = t.toString();

        for (String p : testNode.getSession().getNamespacePrefixes()) {
            if (p.length() != 0) {
                String u = testNode.getSession().getNamespaceURI(p);
                if (u.contains(":")) {
                    testPrefix = p;
                    testNsUri = u;
                }
            }
        }
        assertNotNull(testPrefix);
        assertNotNull(testNsUri);
    }

    @After
    public void tearDown() throws RepositoryException {
        Session s = testNode.getSession();
        s.removeItem(TEST_PATH);
        s.save();
        Repository r = s.getRepository();
        s.logout();
        dispose(r);
    }

    @AfterClass
    public static void disposeStores() throws Exception {
        for (Map.Entry<NodeStoreFixture, NodeStore> e : STORES.entrySet()) {
            e.getKey().dispose(e.getValue());
        }
        STORES.clear();
    }

    @Test
    public void testSimple() {
        nameTest("foo");
    }

    // TODO: questionable exception
    @Test
    public void testDot() {
        unsupportedNameTest(".", ItemExistsException.class);
    }

    @Test
    public void testDotFoo() {
        nameTest(".foo");
    }

    // TODO: questionable exception
    @Test
    public void testDotDot() {
        unsupportedNameTest("..", ItemExistsException.class);
    }

    @Test
    public void testDotDotFoo() {
        nameTest("..foo");
    }

    @Test
    public void testTrailingDot() {
        nameTest("foo.");
    }

    // TODO: questionable exception
    @Test
    public void testLeadingBlank() {
        unsupportedNameTest(" foo", RepositoryException.class);
    }

    // TODO: questionable exception
    @Test
    public void testTrailingBlank() {
        unsupportedNameTest("foo ", RepositoryException.class);
    }

    // TODO: questionable exception
    @Test
    public void testEnclosedSlash() {
        unsupportedNameTest("foo/bar", PathNotFoundException.class);
    }

    // TODO: questionable exception
    @Test
    public void testEnclosedPipe() {
        unsupportedNameTest("foo|bar", PathNotFoundException.class);
    }

    // TODO: questionable exception
    @Test
    public void testEnclosedStar() {
        unsupportedNameTest("foo*bar", PathNotFoundException.class);
    }

    // TODO: questionable exception
    @Test
    public void testEnclosedOpenBracket() {
        unsupportedNameTest("foo[bar", PathNotFoundException.class);
    }

    // TODO: questionable exception
    @Test
    public void testEnclosedCloseBracket() {
        unsupportedNameTest("foo]bar", PathNotFoundException.class);
    }

    // TODO: questionable exception
    @Test
    public void testLeadingColon() {
        unsupportedNameTest(":foo", RepositoryException.class);
    }

    // TODO: questionable exception
    @Test
    public void testEnclosedUnmappedNsColon() {
        unsupportedNameTest(unmappedNsPrefix + ":bar", RepositoryException.class);
    }

    // TODO seems to be a bug
    @Test
    public void testEmptyNameInCurlys() throws RepositoryException {
        Node n = nameTest("{}foo");
        assertEquals("foo", n.getName());
    }

    @Test
    public void testSingleEnclosedOpenCurly() {
        nameTest("foo{bar");
    }

    @Test
    public void testSingleEnclosedCloseCurly() {
        nameTest("foo}bar");
    }

    @Test
    public void testValidLocalNameInCurlys() throws RepositoryException {
        Node n = nameTest("{foo}bar");
        assertEquals("{foo}bar", n.getName());
    }

    // TODO: questionable exception
    @Test
    public void testNonUriInCurlys() {
        unsupportedNameTest("{/}bar", RepositoryException.class);
    }

    @Test
    public void testValidNamespaceUriInCurlys() throws RepositoryException {
        Node n = nameTest("{" + testNsUri + "}foo");
        assertEquals(testPrefix + ":foo", n.getName());
    }

    // TODO: questionable exception
    @Test
    public void testValidNamespaceUriInCurlysWrongPlace() {
        unsupportedNameTest("x{" + testNsUri + "}foo", RepositoryException.class);
    }

    // TODO: questionable exception
    @Test
    public void testValidNamespaceUriInCurlysNoLocalName() {
        unsupportedNameTest("{" + testNsUri + "}", RepositoryException.class);
    }

    // TODO this should actually pass
    @Test
    public void testQualifiedNameWithUnmappedNsUri() {
        String ns = "urn:uuid:" + UUID.randomUUID().toString();
        unsupportedNameTest("{" + ns + "}foo", RepositoryException.class);
    }

    @Test
    public void testEnclosedPercent() {
        nameTest("foo%bar");
    }

    @Test
    public void testEnclosedBlank() {
        nameTest("foo bar");
    }

    @Test
    public void testEnclosedTab() {
        unsupportedNameTest("foo\tbar", RepositoryException.class);
    }

    @Test
    public void testEnclosedLf() {
        unsupportedNameTest("foo\nbar", RepositoryException.class);
    }

    @Test
    public void testEnclosedCr() {
        unsupportedNameTest("foo\rbar", RepositoryException.class);
    }

    @Test
    public void testEnclosedNonXMLChars() {
        // see OAK-7270
        org.junit.Assume.assumeFalse(super.fixture.toString().toLowerCase().contains("rdb"));
        // see https://www.w3.org/TR/xml/#NT-Char
        for (int c = 0; c < 32; c++) {
            if (!(c == 0x9 || c == 0xa || c == 0xd)) {
                unsupportedNameTest("foo" + ((char) c) + "bar", RepositoryException.class);
            }
        }
    }

    @Test
    public void testEnclosedNonBreakingSpace() {
        nameTest("foo\u00a0bar");
    }

    @Test
    public void testEnclosedIdeographicSpace() {
        nameTest("foo\u3000bar");
    }

    @Test
    public void testUnpairedHighSurrogateEnd() {
        // see OAK-5506
        org.junit.Assume.assumeFalse(super.fixture.toString().toLowerCase().contains("segment"));
        org.junit.Assume.assumeFalse(super.fixture.toString().toLowerCase().contains("rdb"));
        nameTest("foo" + SURROGATE_PAIR[0]);
    }

    @Test
    public void testUnpairedLowSurrogateStart() {
        // see OAK-5506
        org.junit.Assume.assumeFalse(super.fixture.toString().toLowerCase().contains("segment"));
        org.junit.Assume.assumeFalse(super.fixture.toString().toLowerCase().contains("rdb"));
        nameTest(SURROGATE_PAIR[1] + "foo");
    }

    @Test
    public void testUnpairedSurrogateInside() {
        // see OAK-5506
        org.junit.Assume.assumeFalse(super.fixture.toString().toLowerCase().contains("segment"));
        // see OAK-7270
        org.junit.Assume.assumeFalse(super.fixture.toString().toLowerCase().contains("rdb"));
        nameTest("foo" + SURROGATE_PAIR[0] + "bar");
        nameTest("foo" + SURROGATE_PAIR[1] + "bar");
    }

    @Test
    public void testSurrogate() {
        nameTest("foo" + new String(SURROGATE_PAIR));
    }

    private Node nameTest(String nodeName) {
        try {
            Node n = testNode.addNode(nodeName);
            testNode.getSession().save();
            Node p = testNode.getSession().getNode(n.getPath());
            assertTrue("nodes should be the same", p.isSame(n));
            assertEquals("paths should be equal", p.getPath(), n.getPath());
            return p;
        } catch (RepositoryException ex) {
            fail(ex.getMessage());
            return null;
        }
    }

    private void unsupportedNameTest(String nodeName, Class<? extends RepositoryException> clazz) {
        try {
            testNode.addNode(nodeName);
            testNode.getSession().save();
            fail("should have failed with " + clazz);
        }
        catch (RepositoryException ex) {
            assertTrue("should have failed with " + clazz + ", but got " + ex.getClass(), clazz.isAssignableFrom(ex.getClass()));
        }
    }

    private Repository createRepository(NodeStoreFixture fixture) throws RepositoryException
            {
        NodeStore ns = null;
        for (Map.Entry<NodeStoreFixture, NodeStore> e : STORES.entrySet()) {
            if (e.getKey().getClass().equals(fixture.getClass())) {
                ns = e.getValue();
            }
        }
        if (ns == null) {
            ns = createNodeStore(fixture);
            STORES.put(fixture, ns);
        }
        return createRepository(ns);
    }
}