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

import static org.apache.sling.resourceresolver.impl.ResourceResolverImpl.PROP_ALIAS;
import static org.apache.sling.spi.resource.provider.ResourceProvider.PROPERTY_NAME;
import static org.apache.sling.spi.resource.provider.ResourceProvider.PROPERTY_ROOT;
import static org.hamcrest.Matchers.is;
import static org.hamcrest.Matchers.notNullValue;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertThat;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;

import java.util.Arrays;
import java.util.HashSet;
import java.util.Set;

import javax.servlet.http.HttpServletRequest;

import org.apache.sling.api.resource.LoginException;
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.mapping.ResourceMapper;
import org.apache.sling.resourceresolver.impl.ResourceAccessSecurityTracker;
import org.apache.sling.resourceresolver.impl.ResourceResolverFactoryActivator;
import org.apache.sling.serviceusermapping.impl.ServiceUserMapperImpl;
import org.apache.sling.spi.resource.provider.ResourceProvider;
import org.apache.sling.testing.mock.osgi.junit.OsgiContext;
import org.junit.After;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
import org.junit.runners.Parameterized.Parameters;

/**
 * Validates that the {@link ResourceMapperImpl} correctly queries all sources of mappings
 * 
 * <p>This test ensures that in case more than one mappings is possible, for instance:
 * 
 * <ol>
 *   <li>path for an existing resource</li>
 *   <li>alias</li>
 *   <li>/etc/map entries</li>
 * </ol>
 * 
 * all are correctly considered and included in the relevant method calls.
 * </p>
 * 
 * <p>This test should not exhaustively test all mapping scenarios, other tests in this
 * module and the Sling ITs cover that.</p>
 *
 */
@RunWith(Parameterized.class)
public class ResourceMapperImplTest {
    
    @Parameters(name="optimized alias resolution → {0}")
    public static Object[] data() {
        return new Object[] { false, true};
    }
    

    @Rule
    public final OsgiContext ctx = new OsgiContext();

    private final boolean optimiseAliasResolution;
    private HttpServletRequest req;
    private ResourceResolver resolver;

    public ResourceMapperImplTest(boolean optimiseAliasResolution) {
        this.optimiseAliasResolution = optimiseAliasResolution;
    }

    @Before
    public void prepare() throws LoginException {

        ctx.registerInjectActivateService(new ServiceUserMapperImpl());
        ctx.registerInjectActivateService(new ResourceAccessSecurityTracker());
        ctx.registerInjectActivateService(new StringInterpolationProviderImpl());

        InMemoryResourceProvider resourceProvider = new InMemoryResourceProvider();
        resourceProvider.putResource("/"); // root
        resourceProvider.putResource("/here"); // regular page
        resourceProvider.putResource("/there", PROP_ALIAS, "alias-value"); // with alias
        resourceProvider.putResource("/there-multiple", PROP_ALIAS, "alias-value-3", "alias-value-4"); // with multivalued alias
        resourceProvider.putResource("/somewhere", PROP_ALIAS, "alias-value-2"); // with alias and also /etc/map
        resourceProvider.putResource("/there/that"); // parent has alias
        resourceProvider.putResource("/content");
        resourceProvider.putResource("/content/virtual");
        resourceProvider.putResource("/content/virtual/foo"); // matches virtual.host.com.80 mapping entry
        resourceProvider.putResource("/parent", PROP_ALIAS, "alias-parent"); // parent has alias
        resourceProvider.putResource("/parent/child", PROP_ALIAS, "alias-child"); // child has alias
        resourceProvider.putResource("/parent/child-multiple", PROP_ALIAS, "alias-child-1", "alias-child-2"); // child has multiple alias
        resourceProvider.putResource("/vain", "sling:vanityPath", "/vanity-a", "/vanity-b"); // vanity path

        // build /etc/map structure
        resourceProvider.putResource("/etc");
        resourceProvider.putResource("/etc/map");
        resourceProvider.putResource("/etc/map/http");
        resourceProvider.putResource("/etc/map/http/localhost_any",
                "sling:internalRedirect", "/somewhere",
                "sling:match", "localhost.8080/everywhere");
        resourceProvider.putResource("/etc/map/http/virtual.host.com.80",
                "sling:internalRedirect", "/content/virtual");
        
        // we fake the fact that we are the JCR resource provider since it's the required one
        ctx.registerService(ResourceProvider.class, resourceProvider, PROPERTY_ROOT, "/", PROPERTY_NAME, "JCR");
        // disable optimised alias resolution as it relies on JCR queries
        ctx.registerInjectActivateService(new ResourceResolverFactoryActivator(),
                "resource.resolver.optimize.alias.resolution", optimiseAliasResolution);
        
        ResourceResolverFactory factory = ctx.getService(ResourceResolverFactory.class);
        
        assertNotNull(factory);
        
        resolver = factory.getResourceResolver(null);
        
        req = mock(HttpServletRequest.class);
        when(req.getScheme()).thenReturn("http");
        when(req.getServerName()).thenReturn("localhost");
        when(req.getServerPort()).thenReturn(8080);
        when(req.getContextPath()).thenReturn("/app");
    }
    
    @After
    public void cleanup() {
        if ( resolver != null )
            resolver.close();
    }
    
    /**
     * Validates that mappings for an empty return the root path
     * 
     * @throws LoginException
     */
    @Test
    public void mapNonExistingEmptyPath() throws LoginException {
        
        ExpectedMappings.nonExistingResource("")
            .singleMapping("/")
            .singleMappingWithRequest("/app/")
            .allMappings("/")
            .allMappingsWithRequest("/app/")
            .verify(resolver, req);
    }
    
    /**
     * Validates that mappings for a non-existing resource only contain that resource's path
     * 
     * @throws LoginException
     */
    @Test
    public void mapNonExistingPath() throws LoginException {
        
        ExpectedMappings.nonExistingResource("/not-here")
            .singleMapping("/not-here")
            .singleMappingWithRequest("/app/not-here")
            .allMappings("/not-here")
            .allMappingsWithRequest("/app/not-here")
            .verify(resolver, req);
    }
    
    /**
     * Validates that mappings for an existing resource only contain that resource's path
     * 
     * @throws LoginException
     */
    @Test
    public void mapExistingPath() throws LoginException {
        
        ExpectedMappings.existingResource("/here")
            .singleMapping("/here")
            .singleMappingWithRequest("/app/here")
            .allMappings("/here")
            .allMappingsWithRequest("/app/here")
            .verify(resolver, req);
    }

    /**
     * Validates that mappings for a existing resource with an alias contain the alias and the resource's path
     * 
     * @throws LoginException
     */
    @Test
    public void mapResourceWithAlias() {
        
        ExpectedMappings.existingResource("/there")
            .singleMapping("/alias-value")
            .singleMappingWithRequest("/app/alias-value")
            .allMappings("/alias-value", "/there")
            .allMappingsWithRequest("/app/alias-value", "/app/there")
            .verify(resolver, req);
    }

    /**
     * Validates that mappings for a existing resource with multiple alias contain the alias and the resource's path
     *
     * @throws LoginException
     */
    @Test
    public void mapResourceWithMultivaluedAlias() {
        
        ExpectedMappings.existingResource("/there-multiple")
                .singleMapping("/alias-value-3")
                .singleMappingWithRequest("/app/alias-value-3")
                .allMappings("/alias-value-3", "/alias-value-4", "/there-multiple")
                .allMappingsWithRequest("/app/alias-value-3", "/app/alias-value-4", "/app/there-multiple")
                .verify(resolver, req);
    }

    /**
     * Validates that mappings for a existing resource with an alias and /etc/map entry
     * contain the /etc/map entry, the alias and the resource's path
     * 
     * @throws LoginException
     */    
    @Test
    public void mapResourceWithAliasAndEtcMap() {
        
        ExpectedMappings.existingResource("/somewhere")
            .singleMapping("/alias-value-2")
            .singleMappingWithRequest("/app/alias-value-2")
            .allMappings("/alias-value-2", "http://localhost:8080/everywhere", "/somewhere")
            .allMappingsWithRequest("/app/alias-value-2", "/app/everywhere", "/app/somewhere")
            .verify(resolver, req);
    }
    
    /**
     * Validates that a resource with an alias on parent has the parent path set
     * to the alias value
     * 
     * @throws LoginException
     */
    @Test
    public void mapResourceWithAliasOnParent() {
        ExpectedMappings.existingResource("/there/that")
            .singleMapping("/alias-value/that")
            .singleMappingWithRequest("/app/alias-value/that")
            .allMappings("/alias-value/that", "/there/that")
            .allMappingsWithRequest("/app/alias-value/that","/app/there/that")
            .verify(resolver, req);       
    }

    @Test
    public void priorityForVHostMappings() {
        // override the default request
        req = mock(HttpServletRequest.class);
        when(req.getScheme()).thenReturn("http");
        when(req.getServerName()).thenReturn("virtual.host.com");
        when(req.getServerPort()).thenReturn(-1);
        when(req.getContextPath()).thenReturn("");
        when(req.getPathInfo()).thenReturn(null);
        
        ExpectedMappings.existingResource("/content/virtual/foo")
            .singleMapping("http://virtual.host.com/foo")
            .singleMappingWithRequest("/foo")
            .allMappings("http://virtual.host.com/foo", "/content/virtual/foo")
            .allMappingsWithRequest("/foo", "/content/virtual/foo")
            .verify(resolver, req);    
        
    }


    /**
     * Validates that a resource with an alias on parent and on child
     *
     * @throws LoginException
     */
    @Test
    public void mapResourceWithNestedAlias() {
        ExpectedMappings.existingResource("/parent/child")
                .singleMapping("/alias-parent/alias-child")
                .singleMappingWithRequest("/app/alias-parent/alias-child")
                .allMappings("/alias-parent/alias-child", "/alias-parent/child", "/parent/alias-child", "/parent/child")
                .allMappingsWithRequest("/app/alias-parent/alias-child", "/app/alias-parent/child", "/app/parent/alias-child", "/app/parent/child")
                .verify(resolver, req);
    }

    /**
     * Validates that a resource with an alias on parent and multiple alias on child
     *
     * @throws LoginException
     */
    @Test
    public void mapResourceWithNestedMultipleAlias() {
        ExpectedMappings.existingResource("/parent/child-multiple")
                .singleMapping("/alias-parent/alias-child-1")
                .singleMappingWithRequest("/app/alias-parent/alias-child-1")
                .allMappings("/alias-parent/alias-child-1", "/alias-parent/alias-child-2", "/alias-parent/child-multiple", "/parent/alias-child-1", "/parent/alias-child-2", "/parent/child-multiple")
                .allMappingsWithRequest("/app/alias-parent/alias-child-1", "/app/alias-parent/alias-child-2", "/app/alias-parent/child-multiple", "/app/parent/alias-child-1", "/app/parent/alias-child-2", "/app/parent/child-multiple")
                .verify(resolver, req);
    }
    
    /**
     * Validates that vanity paths are returned as mappings
     * 
     * <p>As vanity paths are alternate paths rather than variations so they will not be returned
     * from the singleMapping() methods.</p>
     */
    @Test
    public void mapResourceWithVanityPaths() {
        ExpectedMappings.existingResource("/vain")
            .singleMapping("/vain")
            .singleMappingWithRequest("/app/vain")
            .allMappings("/vanity-a", "/vanity-b", "/vain")
            .allMappingsWithRequest("/app/vanity-a", "/app/vanity-b", "/app/vain")
            .verify(resolver, req);
    }

    static class ExpectedMappings {
        
        public static ExpectedMappings existingResource(String path) {
            return new ExpectedMappings(path, true);
        }
        
        public static ExpectedMappings nonExistingResource(String path) {
            return new ExpectedMappings(path, false);
        }
        
        private final String path;
        private final boolean exists;
        
        private String singleMapping;
        private String singleMappingWithRequest;
        private Set<String> allMappings;
        private Set<String> allMappingsWithRequest;
        
        private ExpectedMappings(String path, boolean exists) {
            this.path = path;
            this.exists = exists;
        }

        public ExpectedMappings singleMapping(String singleMapping) {
            this.singleMapping = singleMapping;
            
            return this;
        }
        
        public ExpectedMappings singleMappingWithRequest(String singleMappingWithRequest) {
            this.singleMappingWithRequest = singleMappingWithRequest;
            
            return this;
        }
        
        public ExpectedMappings allMappings(String... allMappings) {
            this.allMappings = new HashSet<>(Arrays.asList(allMappings));
            
            return this;
        }

        public ExpectedMappings allMappingsWithRequest(String... allMappingsWithRequest) {
            this.allMappingsWithRequest = new HashSet<>(Arrays.asList(allMappingsWithRequest));
            
            return this;
        }
        
        public void verify(ResourceResolver resolver, HttpServletRequest request) {
            checkConfigured();
            
            Resource res = resolver.getResource(path);
            if ( exists ) {
                assertThat("Resource was null but should exist", res, notNullValue());
                assertThat("Resource is non-existing but should exist", ResourceUtil.isNonExistingResource(res), is(false));
            } else {
                assertThat("Resource is neither null nor non-existing", res == null || ResourceUtil.isNonExistingResource(res), is(true));
            }

            // downcast to ensure we're testing the right class
            ResourceMapperImpl mapper = (ResourceMapperImpl) resolver.adaptTo(ResourceMapper.class);
            
            assertThat("Single mapping without request", mapper.getMapping(path), is(singleMapping));
            if ( !path.isEmpty() ) // an empty path is invalid, hence not testing with a request
                assertThat("Single mapping with request", mapper.getMapping(path, request), is(singleMappingWithRequest));
            assertThat("All mappings without request", mapper.getAllMappings(path), is(allMappings));
            if ( !path.isEmpty() ) // an empty path is invalid, hence not testing with a request
                assertThat("All mappings with request", mapper.getAllMappings(path, request), is(allMappingsWithRequest));
        }

        private void checkConfigured() {
            if ( singleMapping == null )
                throw new IllegalStateException("singleMapping is null");
            if ( singleMappingWithRequest == null )
                throw new IllegalStateException("singleMappingWithRequest is null");
            if ( allMappings == null )
                throw new IllegalStateException("allMappings is null");
            if ( allMappingsWithRequest == null )
                throw new IllegalStateException("allMappingsWithRequest is null");
        }
    }
}
