/*
 * 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.testing.mock.sling.resource;

import javax.jcr.Node;
import javax.jcr.RepositoryException;
import javax.jcr.Session;

import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import java.util.Map;

import org.apache.commons.collections4.IteratorUtils;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang3.time.DateUtils;
import org.apache.jackrabbit.JcrConstants;
import org.apache.sling.api.resource.PersistenceException;
import org.apache.sling.api.resource.Resource;
import org.apache.sling.api.resource.ResourceUtil;
import org.apache.sling.api.resource.ValueMap;
import org.apache.sling.testing.mock.sling.ResourceResolverType;
import org.apache.sling.testing.mock.sling.junit.SlingContext;
import org.junit.After;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;

import static org.junit.Assert.assertArrayEquals;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;

/**
 * Implements simple write and read resource and values test.
 * JCR API is used to create the test data.
 */
@SuppressWarnings("null")
public abstract class AbstractJcrResourceResolverTest {

    @Rule
    public SlingContext context = new SlingContext(getResourceResolverType());

    private static final String STRING_VALUE = "value1";
    private static final String[] STRING_ARRAY_VALUE = new String[] {"value1", "value2"};
    private static final int INTEGER_VALUE = 25;
    private static final double DOUBLE_VALUE = 3.555d;
    private static final boolean BOOLEAN_VALUE = true;
    private static final Date DATE_VALUE = new Date(10000);
    private static final Calendar CALENDAR_VALUE = Calendar.getInstance();
    private static final byte[] BINARY_VALUE = new byte[] {0x01, 0x02, 0x03, 0x04, 0x05, 0x06};

    private Session session;
    protected Node testRoot;

    protected abstract ResourceResolverType getResourceResolverType();

    @Before
    public final void setUp() throws RepositoryException {
        session = context.resourceResolver().adaptTo(Session.class);

        // prepare some test data using JCR API
        Node rootNode = getTestRootNode();
        Node node1 = rootNode.addNode("node1", JcrConstants.NT_UNSTRUCTURED);

        node1.setProperty("stringProp", STRING_VALUE);
        node1.setProperty("stringArrayProp", STRING_ARRAY_VALUE);
        node1.setProperty("integerProp", INTEGER_VALUE);
        node1.setProperty("doubleProp", DOUBLE_VALUE);
        node1.setProperty("booleanProp", BOOLEAN_VALUE);
        node1.setProperty("dateProp", DateUtils.toCalendar(DATE_VALUE));
        node1.setProperty("calendarProp", CALENDAR_VALUE);
        node1.setProperty("binaryProp", session.getValueFactory().createBinary(new ByteArrayInputStream(BINARY_VALUE)));

        node1.addNode("node11", JcrConstants.NT_UNSTRUCTURED);
        node1.addNode("node12", JcrConstants.NT_UNSTRUCTURED);

        session.save();
    }

    @After
    public final void tearDown() {
        testRoot = null;
    }

    /**
     * Return a test root node, created on demand, with a unique path
     */
    private Node getTestRootNode() throws RepositoryException {
        if (this.testRoot == null) {
            this.testRoot = context.resourceResolver()
                    .getResource(context.uniqueRoot().content())
                    .adaptTo(Node.class);
        }
        return testRoot;
    }

    @Test
    public void testGetResourcesAndValues() throws IOException, RepositoryException {
        Resource resource1 =
                context.resourceResolver().getResource(getTestRootNode().getPath() + "/node1");
        assertNotNull(resource1);
        assertEquals("node1", resource1.getName());

        ValueMap props = ResourceUtil.getValueMap(resource1);
        assertEquals(STRING_VALUE, props.get("stringProp", String.class));
        assertArrayEquals(STRING_ARRAY_VALUE, props.get("stringArrayProp", String[].class));
        assertEquals((Integer) INTEGER_VALUE, props.get("integerProp", Integer.class));
        assertEquals(DOUBLE_VALUE, props.get("doubleProp", Double.class), 0.0001);
        assertEquals(BOOLEAN_VALUE, props.get("booleanProp", Boolean.class));
        assertEquals(DATE_VALUE, props.get("dateProp", Date.class));
        assertEquals(
                CALENDAR_VALUE.getTime(),
                props.get("calendarProp", Calendar.class).getTime());

        Resource binaryPropResource = resource1.getChild("binaryProp");
        InputStream is = binaryPropResource.adaptTo(InputStream.class);
        byte[] dataFromResource = IOUtils.toByteArray(is);
        is.close();
        assertArrayEquals(BINARY_VALUE, dataFromResource);

        // read second time to ensure not the original input stream was returned
        InputStream is2 = binaryPropResource.adaptTo(InputStream.class);
        byte[] dataFromResource2 = IOUtils.toByteArray(is2);
        is2.close();
        assertArrayEquals(BINARY_VALUE, dataFromResource2);

        List<Resource> children = IteratorUtils.toList(resource1.listChildren());
        assertEquals(2, children.size());
        assertEquals("node11", children.get(0).getName());
        assertEquals("node12", children.get(1).getName());
    }

    @Test
    public void testCreateNodeWithPrimaryType() throws RepositoryException, PersistenceException {
        Resource parent =
                context.resourceResolver().getResource(getTestRootNode().getPath());

        Resource child = context.resourceResolver()
                .create(
                        parent,
                        "nodeTypeResource",
                        Map.<String, Object>of("sling:resourceType", JcrConstants.NT_UNSTRUCTURED));
        assertNotNull(child);
        assertEquals(JcrConstants.NT_UNSTRUCTURED, child.getResourceType());
        assertEquals(
                JcrConstants.NT_UNSTRUCTURED,
                child.adaptTo(Node.class).getPrimaryNodeType().getName());
    }

    @Test
    public void testCreateNodeWithResourceType() throws RepositoryException, PersistenceException {
        Resource parent =
                context.resourceResolver().getResource(getTestRootNode().getPath());

        Resource child = ResourceUtil.getOrCreateResource(
                context.resourceResolver(),
                parent.getPath() + "/intermediate/child",
                "sling/resource/type",
                JcrConstants.NT_UNSTRUCTURED,
                true);
        assertNotNull(child);
        assertEquals("sling:OrderedFolder", parent.getResourceType());
        assertEquals("sling/resource/type", child.getResourceType());
    }

    @Test
    public void testPendingChangesCommit() throws Exception {

        // skip this test for JCR_MOCK because it does not track pending changes
        if (getResourceResolverType() == ResourceResolverType.JCR_MOCK) {
            return;
        }

        Resource testRootResource =
                context.resourceResolver().getResource(getTestRootNode().getPath());
        context.resourceResolver().delete(testRootResource);
        assertTrue(session.hasPendingChanges());

        context.resourceResolver().commit();
        assertFalse(session.hasPendingChanges());
    }
}
