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

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

import java.util.ArrayList;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;

import org.apache.commons.collections4.iterators.IteratorIterable;
import org.apache.sling.api.resource.ModifiableValueMap;
import org.apache.sling.api.resource.PersistenceException;
import org.apache.sling.api.resource.Resource;
import org.apache.sling.api.resource.ResourceResolver;
import org.apache.sling.api.resource.ResourceResolverFactory;
import org.apache.sling.api.resource.ResourceUtil;
import org.apache.sling.api.resource.ValueMap;
import org.apache.sling.hamcrest.ResourceMatchers;
import org.apache.sling.resourcemerger.impl.picker.SearchPathBasedResourcePicker;
import org.apache.sling.spi.resource.provider.ResolveContext;
import org.apache.sling.spi.resource.provider.ResourceContext;
import org.apache.sling.testing.resourceresolver.MockHelper;
import org.apache.sling.testing.resourceresolver.MockResourceResolverFactory;
import org.apache.sling.testing.resourceresolver.MockResourceResolverFactoryOptions;
import org.hamcrest.Matchers;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;

public class MergedResourceProviderForSearchPathBasedPickerTest {

    private ResourceResolver resolver;

    private CRUDMergingResourceProvider provider;
    private ResolveContext<Void> ctx;

    @Before public void setup() throws Exception {
        final MockResourceResolverFactoryOptions options = new MockResourceResolverFactoryOptions();
        options.setSearchPaths(new String[] {"/apps/", "/libs/"});
        final ResourceResolverFactory factory = new MockResourceResolverFactory(options);
        this.resolver = factory.getResourceResolver(null);
        MockHelper.create(this.resolver).resource("/apps")
                                          .resource("a").p(MergedResourceConstants.PN_HIDE_CHILDREN, new String[] {"Z", "x", "y"})
                                            .resource("1").p("a", "1").p("b", "2")
                                            .resource(".2").p(ResourceResolver.PROPERTY_RESOURCE_TYPE, "apps")
                                            .resource(".3").p("e", "2")
                                                           .p(MergedResourceConstants.PN_HIDE_PROPERTIES, "*")
                                                           .p("b", "x")
                                                           .p("d", "1")
                                            .resource(".4").p("e", "2")
                                                           .p(MergedResourceConstants.PN_HIDE_PROPERTIES, new String[] {"a", "c"})
                                                           .p("b", "x")
                                                           .p("d", "1")
                                            .resource(".X")
                                          .resource("/apps/b").resource("c").resource("d").resource("e").resource("f")
                                        .resource("/libs")
                                          .resource("deleteTest")
                                          .resource(".mvmTest").p("a", "1").p("b", "2")
                                          .resource(".a")
                                            .resource("1").p("a", "5").p("c", "2")
                                            .resource(".2").p(ResourceResolver.PROPERTY_RESOURCE_TYPE, "libs")
                                            .resource(".3").p("a", "1").p("b", "2").p("c", "3")
                                            .resource(".4").p("a", "1").p("b", "2").p("c", "3")
                                            .resource(".Y")
                                            .resource(".Z")
                                          .resource("/libs/a/Y/a")
                                          .resource("/libs/a/Y/b")
                                          .resource("/libs/a/Y/c")
                                          .resource("/libs/b").resource("c").resource("d").resource("e").resource("f")
                                        .commit();

        this.provider = new CRUDMergingResourceProvider("/merged", new SearchPathBasedResourcePicker(), false);
        this.ctx = new BasicResolveContext(resolver);
    }

    @Test public void testHideChildren() {
        // check preconditions in libs and apps
        assertNotNull(this.resolver.getResource("/libs/a/Z"));
        assertNull(this.resolver.getResource("/libs/a/X"));
        assertNotNull(this.resolver.getResource("/libs/a/Y"));
        assertNull(this.resolver.getResource("/libs/a/x"));
        assertNull(this.resolver.getResource("/libs/a/y"));
        assertNull(this.resolver.getResource("/apps/a/Z"));
        assertNotNull(this.resolver.getResource("/apps/a/X"));
        assertNull(this.resolver.getResource("/apps/a/Y"));
        assertNull(this.resolver.getResource("/apps/a/x"));
        assertNull(this.resolver.getResource("/apps/a/y"));

        // now do the real checks
        assertNull(this.provider.getResource(ctx, "/merged/a/Z", ResourceContext.EMPTY_CONTEXT, null));
        assertNotNull(this.provider.getResource(ctx, "/merged/a/Y", ResourceContext.EMPTY_CONTEXT, null));
        assertNotNull(this.provider.getResource(ctx, "/merged/a/X", ResourceContext.EMPTY_CONTEXT, null));
        assertNull(this.provider.getResource(ctx, "/merged/a/x", ResourceContext.EMPTY_CONTEXT, null));
        assertNull(this.provider.getResource(ctx, "/merged/a/y", ResourceContext.EMPTY_CONTEXT, null));
    }

    @Test public void testListChildren() {
        final Resource rsrcA = this.provider.getResource(ctx, "/merged/a", ResourceContext.EMPTY_CONTEXT, null);
        assertNotNull(rsrcA);
        final Iterator<Resource> i = this.provider.listChildren(ctx, rsrcA);
        assertNotNull(i);
        final List<String> names = new ArrayList<String>();
        while ( i.hasNext() ) {
            names.add(i.next().getName());
        }
        assertEquals(6, names.size());
        assertTrue(names.contains("1"));
        assertTrue(names.contains("2"));
        assertTrue(names.contains("3"));
        assertTrue(names.contains("4"));
        assertTrue(names.contains("Y"));
        assertTrue(names.contains("X"));
    }

    @Test public void testListSubChildren() {
        final Resource rsrcY = this.provider.getResource(ctx, "/merged/a/Y", ResourceContext.EMPTY_CONTEXT, null);
        assertNotNull(rsrcY);
        final Iterator<Resource> i = this.provider.listChildren(ctx, rsrcY);
        assertNotNull(i);
        final List<String> names = new ArrayList<String>();
        while ( i.hasNext() ) {
            names.add(i.next().getName());
        }
        assertEquals(3, names.size());
        assertTrue(names.contains("a"));
        assertTrue(names.contains("b"));
        assertTrue(names.contains("c"));
    }

    @Test public void testProperties() {
        final Resource rsrcA1 = this.provider.getResource(ctx, "/merged/a/1", ResourceContext.EMPTY_CONTEXT, null);
        final ValueMap vm = rsrcA1.adaptTo(ValueMap.class);
        assertNotNull(vm);
        assertEquals(3, vm.size());
        assertEquals("1", vm.get("a"));
        assertEquals("2", vm.get("b"));
        assertEquals("2", vm.get("c"));
    }

    @Test public void testResourceType() {
        // a/2 defines the property and it's overlaid
        final Resource rsrcA2 = this.provider.getResource(ctx, "/merged/a/2", ResourceContext.EMPTY_CONTEXT, null);
        assertEquals("apps", rsrcA2.getResourceType());

        // a/12 doesn't define the property and it's overlaid
        final Resource rsrcA1 = this.provider.getResource(ctx, "/merged/a/1", ResourceContext.EMPTY_CONTEXT, null);
        assertEquals("a/1", rsrcA1.getResourceType());

    }

    @Test public void testClearProperties() {
        final Resource rsrcA3 = this.provider.getResource(ctx, "/merged/a/3", ResourceContext.EMPTY_CONTEXT, null);
        final ValueMap vm = rsrcA3.adaptTo(ValueMap.class);
        assertNotNull(vm);
        // only the properties from the underlying resource should have been cleared (i.e. the ones from /libs)
        assertEquals(3, vm.size());
        assertEquals("2", vm.get("e"));
        assertEquals("x", vm.get("b"));
        assertEquals("1", vm.get("d"));
    }

    @Test public void testHideProperties() {
        final Resource rsrcA4 = this.provider.getResource(ctx, "/merged/a/4", ResourceContext.EMPTY_CONTEXT, null);
        final ValueMap vm = rsrcA4.adaptTo(ValueMap.class);
        assertNotNull(vm);
        assertEquals(3, vm.size());
        assertEquals("1", vm.get("d"));
        assertEquals("2", vm.get("e"));
        assertEquals("x", vm.get("b"));
    }

    @Test public void testSimpleCreateAndDelete() throws PersistenceException {
        final String path = "/merged/a/new";
        try {
            final Resource rsrc = this.provider.create(ctx, path, Collections.singletonMap("foo", (Object)"bla"));
            assertNotNull(rsrc);
            assertEquals(path, rsrc.getPath());
            final ValueMap vm = ResourceUtil.getValueMap(rsrc);
            assertEquals("bla", vm.get("foo"));

            final Resource realResource = this.resolver.getResource("/apps/a/new");
            assertNotNull(realResource);
            final ValueMap vmReal = ResourceUtil.getValueMap(realResource);
            assertEquals("bla", vmReal.get("foo"));
            assertNull(this.resolver.getResource("/libs/a/new"));

            this.provider.delete(ctx, rsrc);
            assertNull(this.provider.getResource(ctx, path, ResourceContext.EMPTY_CONTEXT, null));
            assertNull(this.resolver.getResource("/libs/a/new"));
            assertNull(this.resolver.getResource("/apps/a/new"));

        } finally {
            this.resolver.revert();
        }
    }

    @Test public void testDeleteByHiding() throws PersistenceException {
        final String path = "/merged/deleteTest";
        try {
            assertNotNull(this.resolver.getResource("/libs/deleteTest"));
            assertNull(this.resolver.getResource("/apps/deleteTest"));

            final Resource rsrc = this.provider.getResource(ctx, path, ResourceContext.EMPTY_CONTEXT, null);
            assertNotNull(rsrc);
            assertEquals(path, rsrc.getPath());

            this.provider.delete(ctx, rsrc);

            assertNull(this.provider.getResource(ctx, path, ResourceContext.EMPTY_CONTEXT, null));
            assertNotNull(this.resolver.getResource("/libs/deleteTest"));
            final Resource hidingRsrc = this.resolver.getResource("/apps/deleteTest");
            assertNotNull(hidingRsrc);
            final ValueMap vm = hidingRsrc.getValueMap();
            assertEquals(Boolean.TRUE, vm.get(MergedResourceConstants.PN_HIDE_RESOURCE));

        } finally {
            this.resolver.revert();
        }
    }

    @Test public void testDeleteByHidingAndCreate() throws PersistenceException {
        final String path = "/merged/deleteTest";
        try {
            assertNotNull(this.resolver.getResource("/libs/deleteTest"));
            assertNull(this.resolver.getResource("/apps/deleteTest"));

            final Resource rsrc = this.provider.getResource(ctx, path, ResourceContext.EMPTY_CONTEXT, null);
            assertNotNull(rsrc);
            assertEquals(path, rsrc.getPath());

            this.provider.delete(ctx, rsrc);
            this.provider.create(ctx, path, Collections.singletonMap("foo", (Object)"bla"));

            assertNotNull(this.provider.getResource(ctx, path, ResourceContext.EMPTY_CONTEXT, null));
            assertNotNull(this.resolver.getResource("/libs/deleteTest"));
            final Resource hidingRsrc = this.resolver.getResource("/apps/deleteTest");
            assertNotNull(hidingRsrc);
            final ValueMap vm = hidingRsrc.getValueMap();
            assertEquals("bla", vm.get("foo"));

        } finally {
            this.resolver.revert();
        }
    }

    @Test public void testModifiableValueMap() throws PersistenceException {
        final String path = "/merged/mvmTest";
        try {
            assertNotNull(this.resolver.getResource("/libs/mvmTest"));
            assertNull(this.resolver.getResource("/apps/mvmTest"));

            final Resource rsrc = this.provider.getResource(ctx, path, ResourceContext.EMPTY_CONTEXT, null);
            assertNotNull(rsrc);
            final ValueMap beforeVM = rsrc.getValueMap();
            assertEquals("1", beforeVM.get("a"));
            assertEquals("2", beforeVM.get("b"));

            final ModifiableValueMap mvm = rsrc.adaptTo(ModifiableValueMap.class);
            assertNotNull(mvm);
            assertEquals("1", mvm.get("a"));
            assertEquals("2", mvm.get("b"));

            mvm.put("c", "3");
            mvm.remove("a");

            assertNotNull(this.resolver.getResource("/libs/mvmTest"));
            assertNotNull(this.resolver.getResource("/apps/mvmTest"));

            final Resource rsrc2 = this.provider.getResource(ctx, path, ResourceContext.EMPTY_CONTEXT, null);
            assertNotNull(rsrc2);
            final ValueMap afterVM = rsrc2.getValueMap();
            assertNull(afterVM.get("a"));
            assertEquals("2", afterVM.get("b"));
            assertEquals("3", afterVM.get("c"));

            final Resource rsrcL = this.resolver.getResource("/libs/mvmTest");
            assertEquals("1", rsrcL.getValueMap().get("a"));
            assertEquals("2", rsrcL.getValueMap().get("b"));
            assertNull(rsrcL.getValueMap().get("c"));

            final Resource rsrcA = this.resolver.getResource("/apps/mvmTest");
            assertNull(rsrcA.getValueMap().get("a"));
            assertNull(rsrcA.getValueMap().get("b"));
            assertEquals("3", rsrcA.getValueMap().get("c"));
            final String[] hidden = rsrcA.getValueMap().get(MergedResourceConstants.PN_HIDE_PROPERTIES, String[].class);
            assertNotNull(hidden);
            assertEquals(1, hidden.length);
            assertEquals("a", hidden[0]);

        } finally {
            this.resolver.revert();
        }

    }

    @Test public void testGetWithRelatedResource() {
        final String path = "/merged/b/c/d";
        String[] relatedPaths = new String[] {
                null, // no related resource
                "/merged/a", // not related
                "/merged/b", // parent of parent
                "/merged/b/c", // parent
                "/merged/b/c/d", // itself
                "/merged/b/c/d/e", // child
                "/merged/b/c/d/e/f" // deep child
        };
        for (String relatedPath : relatedPaths) {
            final Resource relatedResource;
            if (relatedPath != null) {
                relatedResource = provider.getResource(ctx, relatedPath, ResourceContext.EMPTY_CONTEXT, null);
                assertNotNull("Not found: " + relatedPath, relatedResource);
            } else {
                relatedResource = null;
            }
            Resource resource = provider.getResource(ctx, path, ResourceContext.EMPTY_CONTEXT, relatedResource);
            assertNotNull(resource);
            assertEquals(path, resource.getPath());
            assertTrue(resource instanceof MergedResource);

            MergedResource mergedResource = (MergedResource) resource;
            List<Resource> mappedResources = mergedResource.getMappedResources();
            assertEquals(2, mappedResources.size());
            assertEquals(mappedResources.get(0).getPath(), "/libs/b/c/d");
            assertEquals(mappedResources.get(1).getPath(), "/apps/b/c/d");
        }
    }

    @Test
    public void testOrderBefore() throws PersistenceException {
        // create new child nodes below base and overlay
        MockHelper.create(this.resolver).resource("/libs/orderbeforetest").resource("/apps/orderbeforetest")
                .resource("/libs/orderbeforetest/create").resource("/libs/orderbeforetest/edit")
                .resource("/libs/orderbeforetest/update").resource("/libs/orderbeforetest/delete")
                .resource("/libs/orderbeforetest/rollout").resource("/apps/orderbeforetest/move")
                .resource("/apps/orderbeforetest/create").p(MergedResourceConstants.PN_ORDER_BEFORE, "edit").commit();

        Resource mergedResource = this.provider.getResource(ctx, "/merged/orderbeforetest",
                ResourceContext.EMPTY_CONTEXT, null);
        // convert the iterator returned by list children into an iterable (to be able
        // to perform some tests)
        IteratorIterable<Resource> iterable = new IteratorIterable<Resource>(provider.listChildren(ctx, mergedResource),
                true);

        Assert.assertThat(iterable,
                Matchers.contains(ResourceMatchers.name("create"), ResourceMatchers.name("edit"),
                        ResourceMatchers.name("update"), ResourceMatchers.name("delete"),
                        ResourceMatchers.name("rollout"), ResourceMatchers.name("move")));
    }
}
