/*
 * 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 static org.apache.sling.jcr.resource.internal.AssertCalendar.assertEqualsCalendar;

import java.io.ByteArrayInputStream;
import java.io.InputStream;
import java.io.Serializable;
import java.lang.reflect.Array;
import java.math.BigDecimal;
import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.TimeZone;
import java.util.concurrent.atomic.AtomicReference;

import javax.jcr.Node;
import javax.jcr.RepositoryException;
import javax.jcr.Session;
import javax.jcr.Value;
import javax.jcr.ValueFactory;
import javax.jcr.nodetype.NodeType;

import org.apache.commons.io.IOUtils;
import org.apache.jackrabbit.util.Text;
import org.apache.sling.api.resource.ModifiableValueMap;
import org.apache.sling.api.resource.ValueMap;
import org.apache.sling.api.resource.external.URIProvider;
import org.apache.sling.commons.classloader.DynamicClassLoaderManager;
import org.apache.sling.commons.testing.jcr.RepositoryTestBase;

public class JcrModifiableValueMapTest extends RepositoryTestBase {

    private String rootPath;

    private Node rootNode;

    public static final byte[] TEST_BYTE_ARRAY = {'T', 'e', 's', 't'};
    public static final String TEST_BYTE_ARRAY_TO_STRING = new String(TEST_BYTE_ARRAY);

    @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()) {
            setProperty(rootNode, entry.getKey().toString(), entry.getValue());
        }
        getSession().save();
    }

    private void setProperty(final Node node,
            final String propertyName,
            final Object propertyValue)
    throws RepositoryException {
        if ( propertyValue == null ) {
            node.setProperty(propertyName, (String)null);
        } else if ( propertyValue.getClass().isArray() ) {
            final int length = Array.getLength(propertyValue);
            final Value[] setValues = new Value[length];
            for(int i=0; i<length; i++) {
                final Object value = Array.get(propertyValue, i);
                setValues[i] = createValue(value, node.getSession());
            }
            node.setProperty(propertyName, setValues);
        } else {
            node.setProperty(propertyName, createValue(propertyValue, node.getSession()));
        }
    }

    Value createValue(final Object value, final Session session)
            throws RepositoryException {
                Value val;
                ValueFactory fac = session.getValueFactory();
                if(value instanceof Calendar) {
                    val = fac.createValue((Calendar)value);
                } else if (value instanceof InputStream) {
                    val = fac.createValue(fac.createBinary((InputStream)value));
                } else if (value instanceof Node) {
                    val = fac.createValue((Node)value);
                } else if (value instanceof BigDecimal) {
                    val = fac.createValue((BigDecimal)value);
                } else if (value instanceof Long) {
                    val = fac.createValue((Long)value);
                } else if (value instanceof Short) {
                    val = fac.createValue((Short)value);
                } else if (value instanceof Integer) {
                    val = fac.createValue((Integer)value);
                } else if (value instanceof Number) {
                    val = fac.createValue(((Number)value).doubleValue());
                } else if (value instanceof Boolean) {
                    val = fac.createValue((Boolean) value);
                } else if ( value instanceof String ) {
                    val = fac.createValue((String)value);
                } else {
                    val = null;
                }
                return val;
            }

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

    private HelperData getHelperData() throws Exception {
        return new HelperData(new AtomicReference<DynamicClassLoaderManager>(), new AtomicReference<URIProvider[]>());
    }

    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 testStreams() throws Exception {
        final ModifiableValueMap pvm = new JcrModifiableValueMap(this.rootNode, getHelperData());
        InputStream stream = new ByteArrayInputStream(TEST_BYTE_ARRAY);
        pvm.put("binary", stream);
        getSession().save();
        final ModifiableValueMap modifiableValueMap2 = new JcrModifiableValueMap(this.rootNode, getHelperData());
        assertTrue("The read stream is not what we wrote.", IOUtils.toString(modifiableValueMap2.get("binary", InputStream.class)).equals
                (TEST_BYTE_ARRAY_TO_STRING));
    }

    public void testPut()
    throws Exception {
        getSession().refresh(false);
        final ModifiableValueMap pvm = new JcrModifiableValueMap(this.rootNode, getHelperData());
        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);

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

        final ModifiableValueMap pvm2 = new JcrModifiableValueMap(this.rootNode, getHelperData());
        assertContains(pvm2, currentlyStored);
    }

    public void testRemove()
    throws Exception {
        getSession().refresh(false);
        final ModifiableValueMap pvm = new JcrModifiableValueMap(this.rootNode, getHelperData());

        final String key = "removeMe";
        final Long longValue = 5L;

        pvm.put(key, longValue);

        final Object removedValue = pvm.remove(key);
        assertTrue(removedValue instanceof Long);
        assertTrue(removedValue == longValue);
        assertFalse(pvm.containsKey(key));
    }

    public void testSerializable()
    throws Exception {
        this.rootNode.getSession().refresh(false);
        final ModifiableValueMap pvm = new JcrModifiableValueMap(this.rootNode, getHelperData());
        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);

        getSession().save();

        final ModifiableValueMap pvm2 = new JcrModifiableValueMap(this.rootNode, getHelperData());
        // 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 ModifiableValueMap pvm = new JcrModifiableValueMap(this.rootNode, getHelperData());
        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 ModifiableValueMap pvm = new JcrModifiableValueMap(testNode, getHelperData());

        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");
        }
        getSession().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 ModifiableValueMap pvm = new JcrModifiableValueMap(testNode, getHelperData());
        pvm.put(TEST_PATH, VALUE);
        pvm.put(PROP1, VALUE1);
        pvm.put(PROP2, VALUE2);
        pvm.put(PROP3, VALUE3);
        getSession().save();

        // read with property map
        final ValueMap vm = new JcrModifiableValueMap(testNode, getHelperData());
        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 ModifiableValueMap pvm = new JcrModifiableValueMap(testNode, getHelperData());
        pvm.put(PROP3, VALUE3);
        pvm.put("jcr:a:b", VALUE3);
        pvm.put("jcr:", VALUE3);
        getSession().save();

        // read with property map
        final ValueMap vm = new JcrModifiableValueMap(testNode, getHelperData());
        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")));
    }

    /**
     * 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);
        }
    }

    /**
     * Test date conversions from Date to Calendar and vice versa when reading or writing from value maps.
     */
    public void testDateConversion() throws Exception {
        this.rootNode.getSession().refresh(false);

        // prepare some date values
        Date dateValue1 = new Date(10000);
        Calendar calendarValue1 = Calendar.getInstance();
        calendarValue1.setTime(dateValue1);

        Date dateValue2 = new Date(20000);
        Calendar calendarValue2 = Calendar.getInstance();
        calendarValue2.setTime(dateValue2);

        Date dateValue3 = new Date(30000);
        Calendar calendarValue3 = Calendar.getInstance();
        calendarValue3.setTime(dateValue3);

        // write property
        final Node testNode = this.rootNode.addNode("dateConversionTest" + System.currentTimeMillis());
        testNode.setProperty(PROP1, calendarValue1);
        testNode.getSession().save();

        // write with property map
        final ModifiableValueMap pvm = new JcrModifiableValueMap(testNode, getHelperData());
        pvm.put(PROP2, dateValue2);
        pvm.put(PROP3, calendarValue3);
        getSession().save();

        // read with property map
        final ValueMap vm = new JcrModifiableValueMap(testNode, getHelperData());
        assertEquals(dateValue1, vm.get(PROP1, Date.class));
        assertEqualsCalendar(calendarValue1, vm.get(PROP1, Calendar.class));
        assertEquals(dateValue2, vm.get(PROP2, Date.class));
        assertEqualsCalendar(calendarValue2, vm.get(PROP2, Calendar.class));
        assertEquals(dateValue3, vm.get(PROP3, Date.class));
        assertEqualsCalendar(calendarValue3, vm.get(PROP3, Calendar.class));

        // check types
        assertTrue(vm.get(PROP1) instanceof Calendar);
        assertTrue(vm.get(PROP2) instanceof InputStream);
        assertTrue(vm.get(PROP3) instanceof Calendar);

        // read properties
        assertEqualsCalendar(calendarValue1, testNode.getProperty(PROP1).getDate());
        assertEqualsCalendar(calendarValue3, testNode.getProperty(PROP3).getDate());

    }

    /**
     * Test conversions involving ZonedDateTime
     */
    public void testZonedDateTimeConversions() throws Exception {
        this.rootNode.getSession().refresh(false);

        String dateAsIso8601 = "2019-07-04T14:05:37.123+02:00";
        ZonedDateTime zonedDateTime = ZonedDateTime.parse(dateAsIso8601, DateTimeFormatter.ISO_OFFSET_DATE_TIME);
        Calendar calendar = Calendar.getInstance(TimeZone.getTimeZone(zonedDateTime.getOffset()));
        calendar.setTimeInMillis(zonedDateTime.toInstant().toEpochMilli());

        // write property
        final Node testNode = this.rootNode.addNode("dateConversionTest" + System.currentTimeMillis());
        testNode.setProperty(PROP1, calendar);
        testNode.getSession().save();

        // write with property map
        final ModifiableValueMap pvm = new JcrModifiableValueMap(testNode, getHelperData());
        pvm.put(PROP2, zonedDateTime);
        pvm.put(PROP3, dateAsIso8601);
        getSession().save();

        // read with property map
        final ValueMap vm = new JcrModifiableValueMap(testNode, getHelperData());

        // check types
        assertTrue(vm.get(PROP1) instanceof Calendar);
        assertTrue(vm.get(PROP2) instanceof Calendar);
        assertTrue(vm.get(PROP3) instanceof String);

        // to ZonedDateTime
        assertEquals(zonedDateTime, vm.get(PROP1, ZonedDateTime.class)); // from Calendar
        assertEquals(zonedDateTime, vm.get(PROP2, ZonedDateTime.class)); // from ZonedDateTime
        assertEquals(zonedDateTime, vm.get(PROP3, ZonedDateTime.class)); // from ISO-8601 String

        // from ZonedDateTime
        assertEqualsCalendar(calendar, vm.get(PROP2, Calendar.class)); // to Calendar
        assertEquals(calendar.getTime(), vm.get(PROP2, Date.class));   // to Date
        assertEquals(dateAsIso8601, vm.get(PROP2, String.class));      // to String


        // read properties
        assertEqualsCalendar(calendar, testNode.getProperty(PROP1).getDate());
        assertEqualsCalendar(calendar, testNode.getProperty(PROP2).getDate());
        assertEqualsCalendar(calendar, testNode.getProperty(PROP3).getDate());

    }

}