/*
 * 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.fsprovider.internal;

import static org.apache.sling.fsprovider.internal.TestUtils.assertFile;
import static org.apache.sling.fsprovider.internal.TestUtils.assertFolder;
import static org.junit.Assert.assertArrayEquals;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertThat;

import java.util.List;

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

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.fsprovider.internal.TestUtils.RegisterFsResourcePlugin;
import org.apache.sling.hamcrest.ResourceMatchers;
import org.apache.sling.testing.mock.sling.ResourceResolverType;
import org.apache.sling.testing.mock.sling.junit.SlingContext;
import org.apache.sling.testing.mock.sling.junit.SlingContextBuilder;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;

import com.google.common.collect.ImmutableList;

/**
 * Test access FileFault XML files, folders and content.
 */
public class FileVaultContentTest {

    private Resource damAsset;
    private Resource sampleContent;

    @Rule
    public SlingContext context = new SlingContextBuilder(ResourceResolverType.JCR_MOCK)
        .plugin(new RegisterFsResourcePlugin(
                "provider.fs.mode", FsMode.FILEVAULT_XML.name(),
                "provider.file", "src/test/resources/vaultfs-test/jcr_root",
                "provider.filevault.filterxml.path", "src/test/resources/vaultfs-test/META-INF/vault/filter.xml",
                "provider.roots", "/content/dam/talk.png"
                ))
        .plugin(new RegisterFsResourcePlugin(
                "provider.fs.mode", FsMode.FILEVAULT_XML.name(),
                "provider.file", "src/test/resources/vaultfs-test/jcr_root",
                "provider.filevault.filterxml.path", "src/test/resources/vaultfs-test/META-INF/vault/filter.xml",
                "provider.roots", "/content/samples"
                ))
        .build();

    @Before
    public void setUp() {
        damAsset = context.resourceResolver().getResource("/content/dam/talk.png");
        sampleContent = context.resourceResolver().getResource("/content/samples");
    }

    @Test
    public void testDamAsset() {
        assertNotNull(damAsset);
        assertEquals("app:Asset", damAsset.getResourceType());
        
        Resource content = damAsset.getChild("jcr:content");
        assertNotNull(content);
        assertEquals("app:AssetContent", content.getResourceType());
        
        Resource metadata = content.getChild("metadata");
        assertNotNull(metadata);
        ValueMap props = ResourceUtil.getValueMap(metadata);
        assertEquals((Integer)4, props.get("app:Bitsperpixel", Integer.class));
        
        assertFolder(content, "renditions");
        assertFile(content, "renditions/original", null);
        assertFile(content, "renditions/web.1280.1280.png", null);
    }

    @Test
    public void testSampleContent() {
        assertNotNull(sampleContent);
        assertEquals("sling:OrderedFolder", sampleContent.getResourceType());

        Resource enContent = sampleContent.getChild("en/jcr:content");
        assertArrayEquals(new String[] { "/etc/mobile/groups/responsive" }, ResourceUtil.getValueMap(enContent).get("app:deviceGroups", String[].class));
    }

    @Test
    public void testListChildren() {
        Resource en = sampleContent.getChild("en");
        List<Resource> children = ImmutableList.copyOf(en.listChildren());
        assertEquals(3, children.size());
        
        Resource child1 = children.get(0);
        assertEquals("jcr:content", child1.getName());
        assertEquals("samples/sample-app/components/content/page/homepage", child1.getResourceType());
 
        Resource child2 = children.get(1);
        assertEquals("tools", child2.getName());
        assertEquals("app:Page", child2.getResourceType());
        
        Resource child3 = children.get(2);
        assertEquals("extra", child3.getName());
        
        // another child (conference) is hidden because of filter
    }

    @Test
    public void testJcrMixedContent() throws RepositoryException {
        // prepare mixed JCR content
        Node root = context.resourceResolver().adaptTo(Session.class).getNode("/");
        Node content = root.addNode("content", "nt:folder");
        Node samples = content.addNode("samples", "nt:folder");
        Node en = samples.addNode("en", "nt:folder");
        Node conference = en.addNode("conference", "nt:folder");
        conference.addNode("page2", "nt:folder");
        samples.addNode("it", "nt:folder");
        
        // pass-through because of filter
        assertNotNull(context.resourceResolver().getResource("/content/samples/en/conference"));
        assertNotNull(sampleContent.getChild("en/conference"));
        assertNotNull(context.resourceResolver().getResource("/content/samples/en/conference/page2"));
        assertNotNull(sampleContent.getChild("en/conference/page2"));

        // list children with mixed content
        Resource enResource = sampleContent.getChild("en");
        assertThat(enResource, ResourceMatchers.containsChildren("jcr:content", "tools", "extra", "conference"));
    }

    @Test
    public void testExtraContent() throws RepositoryException {
        Resource extraContent = sampleContent.getChild("en/extra/extracontent");
        assertNotNull(extraContent);
        assertEquals("apps/app1/components/comp1", extraContent.getResourceType());
        
        Resource layout = extraContent.getChild("layout");
        assertNotNull(layout);
        assertEquals("apps/app1/components/comp2", layout.getResourceType());

        Resource binaryFile = sampleContent.getChild("en/extra/binaryfile.xml");
        assertNotNull(binaryFile);
        assertEquals("nt:file", binaryFile.getResourceType());
    }
    
}
