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

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.fail;
import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.Mockito.when;

import java.util.HashMap;
import java.util.Map;
import java.util.Random;
import java.util.UUID;

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.ResourceUtil;
import org.apache.sling.commons.mime.MimeTypeService;
import org.apache.sling.resourcebuilder.api.ResourceBuilder;
import org.apache.sling.resourcebuilder.test.ResourceAssertions;
import org.apache.sling.testing.resourceresolver.MockResourceResolverFactory;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.junit.MockitoJUnitRunner;

@RunWith(MockitoJUnitRunner.class)
@SuppressWarnings("null")
public class ResourceBuilderImplTest {
    
    private String testRootPath;
    private long lastModified;
    private Random random = new Random(System.currentTimeMillis());
    private ResourceAssertions A;
    
    @Mock
    private MimeTypeService mimeTypeService;
    
    private ResourceResolver resourceResolver;
    
    private Resource getTestRoot(String path) throws PersistenceException {
        final Resource root = resourceResolver.resolve("/");
        assertNotNull("Expecting non-null root", root);
        return resourceResolver.create(root, ResourceUtil.getName(path), null);
    }
    
    private ResourceBuilderImpl getBuilder(String path) throws Exception {
        lastModified = random.nextLong();
        
        final Resource parent = getTestRoot(path);
        final ResourceBuilderImpl result = new ResourceBuilderImpl(parent, mimeTypeService) {
            @Override
            protected long getLastModified(long userSuppliedValue) {
                final long now = System.currentTimeMillis();
                final long superValue = super.getLastModified(-1);
                final long maxDelta = 60 * 1000L;
                if(superValue < now || superValue - now > maxDelta) {
                    fail("getLastModified does not seem to use current time as its default value");
                }
                
                if(userSuppliedValue >= 0) {
                    return super.getLastModified(userSuppliedValue);
                }
                return lastModified;
            }
        };
        return result;
    }
    
    @Before
    public void setup() throws Exception {
        when(mimeTypeService.getMimeType(anyString())).thenReturn("application/javascript");
        resourceResolver = new MockResourceResolverFactory().getResourceResolver(null);
        
        testRootPath = "/" + UUID.randomUUID().toString();
        A = new ResourceAssertions(testRootPath, resourceResolver);
    }
    
    @After
    public void cleanup() throws PersistenceException {
        final Resource r = resourceResolver.getResource(testRootPath);
        if(r != null) {
            resourceResolver.delete(r);
            resourceResolver.commit();
        }
    }
    
    @Test
    public void basicResource() throws Exception {
        getBuilder(testRootPath)
            .resource("child", "title", "foo")
            .commit();
        
        A.assertProperties("child", "title", "foo");
        assertEquals(A.fullPath("child"), A.assertResource("child").getPath());
    }
    
    @Test
    public void basicResourceWithMap() throws Exception {
        Map<String,Object> props = new HashMap<String,Object>();
        props.put("title", "foo");
        getBuilder(testRootPath)
            .resource("child", props)
            .commit();
        
        A.assertProperties("child", "title", "foo");
        assertEquals(A.fullPath("child"), A.assertResource("child").getPath());
    }
    
    @Test
    public void ensureResourceExists() throws Exception {
        
        class MyResourceBuilder extends ResourceBuilderImpl {
            MyResourceBuilder() {
                super(resourceResolver.getResource("/"), null);
            }
            
            Resource r(String path) {
                return ensureResourceExists(path);
            }
        };
        final MyResourceBuilder b = new MyResourceBuilder();
        
        assertEquals("/", b.r(null).getPath());
        assertEquals("/", b.r("").getPath());
        assertEquals("/", b.r("/").getPath());
    }
    
    @Test
    public void deepResource() throws Exception {
        getBuilder(testRootPath)
            .resource("a/b/c", "title", "foo")
            .commit();
        
        A.assertProperties("a/b/c", "title", "foo");
        assertEquals(A.fullPath("a/b/c"), A.assertResource("a/b/c").getPath());
        A.assertResource("a/b");
        A.assertResource("a");
    }
    
    @Test
    public void intermediatePrimaryTypes() throws Exception {
        getBuilder(testRootPath)
            .resource("a/b/c")
            .withIntermediatePrimaryType("foo")
            .resource("d/e")
            .withIntermediatePrimaryType(null)
            .resource("f/g")
            .commit();
        
        A.assertProperties("a/b", ResourceBuilderImpl.JCR_PRIMARYTYPE, "nt:unstructured");
        A.assertProperties("a/b/c/d", ResourceBuilderImpl.JCR_PRIMARYTYPE, "foo");
        A.assertProperties("a/b/c/d/e/f", ResourceBuilderImpl.JCR_PRIMARYTYPE, "nt:unstructured");
    }
    
    @Test
    public void resetParent() throws Exception {
        getBuilder(testRootPath)
            .resource("a/b/c")
            .siblingsMode()
            .resource("one")
            .resource("two")
            .atParent()  // also sets hierarchyMode
            .resource("d/e")
            .resource("f/g")
            .siblingsMode()
            .resource("three")
            .resource("four")
            .commit();
        
        A.assertResource("a/b/c");
        A.assertResource("a/b/c/one");
        A.assertResource("a/b/c/two");
        A.assertResource("d/e");
        A.assertResource("d/e/f/g");
        A.assertResource("d/e/f/g/three");
        A.assertResource("d/e/f/g/four");
    }
    
    @Test
    public void noResetParent() throws Exception {
        getBuilder(testRootPath)
            .resource("a/b/c")
            .resource("d/e")
            .commit();
        
        A.assertResource("a/b/c");
        A.assertResource("a/b/c/d/e");
    }
    
    @Test
    public void getParent() throws Exception {
        final Resource parent = getBuilder(testRootPath).getCurrentParent();
        assertNotNull(parent);
        assertEquals(testRootPath, parent.getPath());
    }
    
    @Test(expected=RuntimeException.class)
    public void missingParentFails() throws Exception {
        new ResourceBuilderImpl(null, null).resource("foo");
    }
    
    @Test(expected=IllegalArgumentException.class)
    public void aboveParentFails() throws Exception {
        getBuilder(testRootPath).resource("../foo");
    }
    
    @Test(expected=IllegalArgumentException.class)
    public void aboveParentFailsFile() throws Exception {
        getBuilder(testRootPath).file("../foo.js", null);
    }
    
    @Test
    public void simpleTree() throws Exception {
        getBuilder(testRootPath)
            .resource("a/b/c", "title", "foo", "count", 21)
            .siblingsMode()
            .resource("1")
            .resource("2")
            .resource("3")
            .hierarchyMode()
            .resource("with")
            .resource("more/here", "it", "worked")
            .resource("deepest", "it", "worked")
            .commit();
        
        A.assertProperties("a/b/c", "count", 21, "title", "foo");
        A.assertProperties("a/b/c/with/more/here", "it", "worked");
        A.assertResource("a/b/c/with/more/here/deepest");
        A.assertResource("a/b/c/1");
        A.assertResource("a/b/c/2");
        A.assertResource("a/b/c/3");
    }
    
    @Test
    public void treeWithFiles() throws Exception {
        getBuilder(testRootPath)
            .resource("apps/myapp/components/resource")
            .siblingsMode()
            .file("models.js", getClass().getResourceAsStream("/files/models.js"), "MT1", 42)
            .file("text.html", getClass().getResourceAsStream("/files/text.html"), "MT2", 43)
            .atParent()
            .file("apps/myapp.json", getClass().getResourceAsStream("/files/myapp.json"), "MT3", 44)
            .atParent()
            .resource("apps/content/myapp/resource")
            .atParent()
            .resource("apps/content", "title", "foo")
            .file("myapp.json", getClass().getResourceAsStream("/files/myapp.json"), "MT4", 45)
            .commit()
            ;
        
        A.assertResource("apps/content/myapp/resource");
        A.assertResource("apps/myapp/components/resource");
        A.assertProperties("apps/content", "title", "foo");
        
        A.assertFile("apps/myapp/components/resource/models.js", 
                "MT1", "function someJavascriptFunction()", 42L);
        A.assertFile("apps/myapp/components/resource/text.html", 
                "MT2", "This is an html file", 43L);
        A.assertFile("apps/myapp.json", 
                "MT3", "\"sling:resourceType\":\"its/resource/type\"", 44L);
        A.assertFile("apps/content/myapp.json", 
                "MT4", "\"sling:resourceType\":\"its/resource/type\"", 45L);
    }
    
    @Test
    public void autoMimetype() throws Exception {
        getBuilder(testRootPath)
            .file("models.js", getClass().getResourceAsStream("/files/models.js"), null, 42)
            .commit()
            ;
        A.assertFile("models.js", 
                "application/javascript", "function someJavascriptFunction()", 42L);
    }
    
    @Test
    public void autoLastModified() throws Exception {
        getBuilder(testRootPath)
            .file("models.js", getClass().getResourceAsStream("/files/models.js"), "MT1", -1)
            .commit()
            ;
        A.assertFile("models.js", 
                "MT1", "function someJavascriptFunction()", lastModified);
    }
    
    @Test
    public void autoEverything() throws Exception {
        getBuilder(testRootPath)
            .file("a/b/c/models.js", getClass().getResourceAsStream("/files/models.js"))
            .commit()
            ;
        A.assertFile("a/b/c/models.js", 
                "application/javascript", "function someJavascriptFunction()", lastModified);
    }
    
    @Test(expected=IllegalStateException.class)
    public void duplicatedFileFails() throws Exception {
        getBuilder(testRootPath)
            .siblingsMode()
            .file("models.js", getClass().getResourceAsStream("/files/models.js"), null, 42)
            .file("models.js", getClass().getResourceAsStream("/files/models.js"), null, 42)
            ;
    }
    
    @Test(expected=IllegalArgumentException.class)
    public void nullDataFails() throws Exception {
        getBuilder(testRootPath)
            .file("models.js", null, null, 42)
            ;
    }
    
    @Test
    public void forParent() throws PersistenceException {
        new ResourceBuilderFactoryService()
            .forParent(getTestRoot(testRootPath))
            .resource("a/b/c")
            .commit();
        A.assertResource("a/b/c");
    }
    
    @Test
    public void forResolver() throws PersistenceException {
        new ResourceBuilderFactoryService()
            .forResolver(resourceResolver)
            .resource("d/e/f")
            .commit();
        
        // Resource is created at root in this case
        A.assertResource("/d/e/f");
    }

    @Test
    public void absolutePath() throws Exception {
        new ResourceBuilderFactoryService()
            .forResolver(resourceResolver)
            .resource("/a/b/c")
            .resource("/a/b/f")
            .resource("/g/h/i")
            .resource("j/l/m")
            .resource("/o/p/q");
        
        // absolute paths are supported and can be mixed with relative paths
        A.assertResource("/a/b/c");
        A.assertResource("/a/b/f");
        A.assertResource("/g/h/i");
        A.assertResource("/g/h/i/j/l/m");
        A.assertResource("/o/p/q");
    }

    @Test
    public void absolutePathSwitchBackToSiblingMode() throws Exception {
        new ResourceBuilderFactoryService()
            .forResolver(resourceResolver)
            .resource("/a").siblingsMode().resource("a1").resource("a2")
            .resource("/b").siblingsMode().resource("b1").resource("b2")
            .resource("/c").resource("c1").resource("c11");
        
        // make sure sibling mode is switched back to hierarchy mode when absolute resources is used
        A.assertResource("/a");
        A.assertResource("/a/a1");
        A.assertResource("/a/a2");
        A.assertResource("/b");
        A.assertResource("/b/b1");
        A.assertResource("/b/b2");
        A.assertResource("/c");
        A.assertResource("/c/c1");
        A.assertResource("/c/c1/c11");
    }

    @Test
    public void reuseInstance() throws Exception {
        ResourceBuilder content = new ResourceBuilderFactoryService()
                .forResolver(resourceResolver)
                .resource("/content");
        content.resource("a");
        content.resource("b/c");
        content.resource("/test")
                .siblingsMode()
                .resource("1")
                .resource("2");

        A.assertResource("/content/a");
        A.assertResource("/content/b/c");
        A.assertResource("/test");
        A.assertResource("/test/1");
        A.assertResource("/test/2");
    }

}
