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

import java.io.Serializable;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

import javax.jcr.Node;
import javax.jcr.RepositoryException;
import javax.jcr.nodetype.NodeType;

import org.apache.jackrabbit.util.Text;
import org.apache.sling.api.resource.PersistableValueMap;
import org.apache.sling.api.resource.ValueMap;
import org.apache.sling.jcr.resource.JcrModifiablePropertyMap;
import org.apache.sling.jcr.resource.JcrPropertyMap;
import org.apache.sling.jcr.resource.JcrResourceUtil;

public class JcrModifiablePropertyMapTest extends JcrPropertyMapTest {

    private String rootPath;

    private Node rootNode;

    @Override
    protected void setUp() throws Exception {
        super.setUp();

        rootPath = "/test_" + System.currentTimeMillis();
        rootNode = getSession().getRootNode().addNode(rootPath.substring(1),
            "nt:unstructured");

        final Map<String, Object> values = this.initialSet();
        for(Map.Entry<String, Object> entry : values.entrySet()) {
            JcrResourceUtil.setProperty(rootNode, entry.getKey().toString(), entry.getValue());
        }
        session.save();
    }

    @Override
    protected void tearDown() throws Exception {
        if (rootNode != null) {
            rootNode.remove();
            session.save();
        }

        super.tearDown();
    }

    private Map<String, Object> initialSet() {
        final Map<String, Object> values = new HashMap<String, Object>();
        values.put("string", "test");
        values.put("long", 1L);
        values.put("bool", Boolean.TRUE);
        return values;
    }

    public void testPut()
    throws Exception {
        this.rootNode.getSession().refresh(false);
        final PersistableValueMap pvm = new JcrModifiablePropertyMap(this.rootNode);
        assertContains(pvm, initialSet());
        assertNull(pvm.get("something"));

        // now put two values and check set again
        pvm.put("something", "Another value");
        pvm.put("string", "overwrite");

        final Map<String, Object> currentlyStored = this.initialSet();
        currentlyStored.put("something", "Another value");
        currentlyStored.put("string", "overwrite");
        assertContains(pvm, currentlyStored);

        pvm.save();
        assertContains(pvm, currentlyStored);

        final PersistableValueMap pvm2 = new JcrModifiablePropertyMap(this.rootNode);
        assertContains(pvm2, currentlyStored);
    }

    public void testReset()
    throws Exception {
        this.rootNode.getSession().refresh(false);
        final PersistableValueMap pvm = new JcrModifiablePropertyMap(this.rootNode);
        assertContains(pvm, initialSet());
        assertNull(pvm.get("something"));

        // now put two values and check set again
        pvm.put("something", "Another value");
        pvm.put("string", "overwrite");

        final Map<String, Object> currentlyStored = this.initialSet();
        currentlyStored.put("something", "Another value");
        currentlyStored.put("string", "overwrite");
        assertContains(pvm, currentlyStored);

        pvm.reset();
        assertContains(pvm, initialSet());

        final PersistableValueMap pvm2 = new JcrModifiablePropertyMap(this.rootNode);
        assertContains(pvm2, initialSet());
    }

    public void testSerializable()
    throws Exception {
        this.rootNode.getSession().refresh(false);
        final PersistableValueMap pvm = new JcrModifiablePropertyMap(this.rootNode);
        assertContains(pvm, initialSet());
        assertNull(pvm.get("something"));

        // now put a serializable object
        final List<String> strings = new ArrayList<String>();
        strings.add("a");
        strings.add("b");
        pvm.put("something", strings);

        // check if we get the list again
        @SuppressWarnings("unchecked")
        final List<String> strings2 = (List<String>) pvm.get("something");
        assertEquals(strings, strings2);

        pvm.save();

        final PersistableValueMap pvm2 = new JcrModifiablePropertyMap(this.rootNode);
        // check if we get the list again
        @SuppressWarnings("unchecked")
        final List<String> strings3 = (List<String>) pvm2.get("something", Serializable.class);
        assertEquals(strings, strings3);

    }

    public void testExceptions() throws Exception {
        this.rootNode.getSession().refresh(false);
        final PersistableValueMap pvm = new JcrModifiablePropertyMap(this.rootNode);
        try {
            pvm.put(null, "something");
            fail("Put with null key");
        } catch (NullPointerException iae) {}
        try {
            pvm.put("something", null);
            fail("Put with null value");
        } catch (NullPointerException iae) {}
        try {
            pvm.put("something", pvm);
            fail("Put with non serializable");
        } catch (IllegalArgumentException iae) {}
    }

    private Set<String> getMixinNodeTypes(final Node node) throws RepositoryException {
        final Set<String> mixinTypes = new HashSet<String>();
        for(final NodeType mixinNodeType : node.getMixinNodeTypes() ) {
            mixinTypes.add(mixinNodeType.getName());
        }
        return mixinTypes;
    }

    public void testMixins() throws Exception {
        this.rootNode.getSession().refresh(false);
        final Node testNode = this.rootNode.addNode("testMixins" + System.currentTimeMillis());
        testNode.getSession().save();
        final PersistableValueMap pvm = new JcrModifiablePropertyMap(testNode);

        final String[] types = pvm.get("jcr:mixinTypes", String[].class);
        final Set<String> exNodeTypes = getMixinNodeTypes(testNode);

        assertEquals(exNodeTypes.size(), (types == null ? 0 : types.length));
        if ( types != null ) {
            for(final String name : types) {
                assertTrue(exNodeTypes.contains(name));
            }
            String[] newTypes = new String[types.length + 1];
            System.arraycopy(types, 0, newTypes, 0, types.length);
            newTypes[types.length] = "mix:referenceable";
            pvm.put("jcr:mixinTypes", newTypes);
        } else {
            pvm.put("jcr:mixinTypes", "mix:referenceable");
        }
        pvm.save();

        final Set<String> newNodeTypes = getMixinNodeTypes(testNode);
        assertEquals(newNodeTypes.size(), exNodeTypes.size() + 1);
    }

    private static final String TEST_PATH = "a<a";

    private static final String VALUE = "value";
    private static final String VALUE1 = "value";
    private static final String VALUE2 = "value";
    private static final String VALUE3 = "my title";
    private static final String PROP1 = "-prop";
    private static final String PROP2 = "1prop";
    private static final String PROP3 = "jcr:title";

    public void testNamesReverse() throws Exception {
        this.rootNode.getSession().refresh(false);

        final Node testNode = this.rootNode.addNode("nameTest" + System.currentTimeMillis());
        testNode.getSession().save();
        final PersistableValueMap pvm = new JcrModifiablePropertyMap(testNode);
        pvm.put(TEST_PATH, VALUE);
        pvm.put(PROP1, VALUE1);
        pvm.put(PROP2, VALUE2);
        pvm.put(PROP3, VALUE3);
        pvm.save();

        // read with property map
        final ValueMap vm = this.createPropertyMap(testNode);
        assertEquals(VALUE, vm.get(TEST_PATH));
        assertEquals(VALUE1, vm.get(PROP1));
        assertEquals(VALUE2, vm.get(PROP2));
        assertEquals(VALUE3, vm.get(PROP3));

        // read properties
        assertEquals(VALUE, testNode.getProperty(TEST_PATH).getString());
        assertEquals(VALUE1, testNode.getProperty(PROP1).getString());
        assertEquals(VALUE2, testNode.getProperty(PROP2).getString());
        assertEquals(VALUE3, testNode.getProperty(PROP3).getString());
    }

    /**
     * Checks property names encoding, see SLING-2502.
     */
    public void testNamesUpdate() throws Exception {
        this.rootNode.getSession().refresh(false);

        final Node testNode = this.rootNode.addNode("nameUpdateTest"
                + System.currentTimeMillis());
        testNode.setProperty(PROP3, VALUE);
        testNode.getSession().save();

        final PersistableValueMap pvm = new JcrModifiablePropertyMap(testNode);
        pvm.put(PROP3, VALUE3);
        pvm.put("jcr:a:b", VALUE3);
        pvm.put("jcr:", VALUE3);
        pvm.save();

        // read with property map
        final ValueMap vm = this.createPropertyMap(testNode);
        assertEquals(VALUE3, vm.get(PROP3));
        assertEquals(VALUE3, vm.get("jcr:a:b"));
        assertEquals(VALUE3, vm.get("jcr:"));

        // read properties
        assertEquals(VALUE3, testNode.getProperty(PROP3).getString());
        assertEquals(VALUE3, testNode.getProperty("jcr:"+Text.escapeIllegalJcrChars("a:b")).getString());
        assertEquals(VALUE3, testNode.getProperty(Text.escapeIllegalJcrChars("jcr:")).getString());
        assertFalse(testNode.hasProperty(Text.escapeIllegalJcrChars(PROP3)));
        assertFalse(testNode.hasProperty(Text.escapeIllegalJcrChars("jcr:a:b")));
    }

    protected JcrPropertyMap createPropertyMap(final Node node) {
        return new JcrModifiablePropertyMap(node);
    }

    /**
     * Check that the value map contains all supplied values
     */
    private void assertContains(ValueMap map, Map<String, Object> values) {
        for(Map.Entry<String, Object> entry : values.entrySet()) {
            final Object stored = map.get(entry.getKey());
            assertEquals(values.get(entry.getKey()), stored);
        }
    }
}
