/*
 * 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.feature.cpconverter;

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

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.Reader;
import java.io.StringReader;
import java.net.URL;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.*;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;

import javax.json.Json;
import javax.json.JsonArray;
import javax.json.JsonObject;

import org.apache.commons.io.FileUtils;
import org.apache.jackrabbit.vault.packaging.CyclicDependencyException;
import org.apache.jackrabbit.vault.packaging.PackageId;
import org.apache.jackrabbit.vault.packaging.PackageProperties;
import org.apache.jackrabbit.vault.packaging.VaultPackage;
import org.apache.jackrabbit.vault.packaging.impl.PackageManagerImpl;
import org.apache.jackrabbit.vault.util.Constants;
import org.apache.sling.feature.ArtifactId;
import org.apache.sling.feature.Artifacts;
import org.apache.sling.feature.Configuration;
import org.apache.sling.feature.Extension;
import org.apache.sling.feature.ExtensionType;
import org.apache.sling.feature.Feature;
import org.apache.sling.feature.cpconverter.accesscontrol.DefaultAclManager;
import org.apache.sling.feature.cpconverter.artifacts.DefaultArtifactsDeployer;
import org.apache.sling.feature.cpconverter.features.DefaultFeaturesManager;
import org.apache.sling.feature.cpconverter.filtering.RegexBasedResourceFilter;
import org.apache.sling.feature.cpconverter.handlers.DefaultEntryHandlersManager;
import org.apache.sling.feature.cpconverter.handlers.EntryHandlersManager;
import org.apache.sling.feature.cpconverter.vltpkg.DefaultPackagesEventsEmitter;
import org.apache.sling.feature.io.json.FeatureJSONReader;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;

public class ContentPackage2FeatureModelConverterTest {

    /**
     * Test package A-1.0. Depends on B and C-1.X
     * Test package B-1.0. Depends on C
     */
    private static String[] TEST_PACKAGES_INPUT = { "test_c-1.0.zip", "test_a-1.0.zip", "test_b-1.0.zip" };

    private static String[] TEST_PACKAGES_OUTPUT = { "my_packages:test_c:1.0", "my_packages:test_b:1.0", "my_packages:test_a:1.0" };

    private static String[] TEST_PACKAGES_CYCLIC_DEPENDENCY = { "test_d-1.0.zip",
                                                                "test_c-1.0.zip",
                                                                "test_a-1.0.zip",
                                                                "test_b-1.0.zip",
                                                                "test_e-1.0.zip" };

    private ContentPackage2FeatureModelConverter converter;
    private EntryHandlersManager handlersManager;

    @Before
    public void setUp() {
        handlersManager = new DefaultEntryHandlersManager();
        converter = new ContentPackage2FeatureModelConverter()
                    .setEntryHandlersManager(handlersManager)
                    .setAclManager(new DefaultAclManager());
    }

    @After
    public void tearDown() {
        converter.cleanup();
    }

    @Test
    public void testHandlersPresent() {
        assertNotNull(handlersManager.getEntryHandlerByEntryPath("/jcr_root/_rep_policy.xml"));
        assertNotNull(handlersManager.getEntryHandlerByEntryPath("/jcr_root/_rep_repoPolicy.xml"));
    }

    @Test(expected = NullPointerException.class)
    public void convertRequiresNonNullPackage() throws Exception {
        converter.convert((File)null);
    }

    @Test(expected = NullPointerException.class)
    public void convertRequiresNonNullPackages() throws Exception {
        converter.convert((File[])null);
    }

    @Test(expected = IllegalArgumentException.class)
    public void convertRequiresExistingFile() throws Exception {
        converter.convert(new File("this/file/does/not/exist.zip"));
    }

    @Test(expected = IllegalArgumentException.class)
    public void convertRequiresNotDirectoryFile() throws Exception {
        File testDirectory = new File(System.getProperty("user.dir"));
        converter.convert(testDirectory);
    }

    @Test(expected = NullPointerException.class)
    public void processRequiresNotNullPackage() throws Exception {
        converter.processSubPackage("", null, null, false);
    }

    @Test
    public void convertContentPackage() throws Exception {
        URL packageUrl = getClass().getResource("test-content-package.zip");
        File packageFile = FileUtils.toFile(packageUrl);

        File outputDirectory = new File(System.getProperty("java.io.tmpdir"), getClass().getName() + '_' + System.currentTimeMillis());

        try {

            converter.setFeaturesManager(new DefaultFeaturesManager(true, 5, outputDirectory, null, null, null, new DefaultAclManager()))
                    .setBundlesDeployer(new DefaultArtifactsDeployer(outputDirectory))
                    .setEmitter(DefaultPackagesEventsEmitter.open(outputDirectory))
                    .convert(packageFile);

            verifyFeatureFile(outputDirectory,
                            "asd.retail.all.json",
                            "asd.sample:asd.retail.all:slingosgifeature:0.0.1",
                            Arrays.asList("org.apache.felix:org.apache.felix.framework:6.0.1"),
                            Arrays.asList("org.apache.sling.commons.log.LogManager.factory.config~asd-retail"),
                            Arrays.asList("asd.sample:asd.retail.apps:zip:cp2fm-converted:0.0.1",
                                            "asd.sample:Asd.Retail.ui.content:zip:cp2fm-converted:0.0.1",
                                            "asd:Asd.Retail.config:zip:cp2fm-converted:0.0.1",
                                            "asd.sample:asd.retail.all:zip:cp2fm-converted:0.0.1"));
            verifyFeatureFile(outputDirectory,
                            "asd.retail.all-author.json",
                            "asd.sample:asd.retail.all:slingosgifeature:author:0.0.1",
                            Arrays.asList("org.apache.sling:org.apache.sling.api:2.20.0"),
                            Collections.emptyList(),
                            Collections.emptyList());
            verifyFeatureFile(outputDirectory,
                            "asd.retail.all-publish.json",
                            "asd.sample:asd.retail.all:slingosgifeature:publish:0.0.1",
                            Arrays.asList("org.apache.sling:org.apache.sling.models.api:1.3.8"),
                            Arrays.asList("org.apache.sling.serviceusermapping.impl.ServiceUserMapperImpl.amended~asd-retail"),
                            Collections.emptyList());

            // verify the runmode.mapper integrity
            File runmodeMapperFile = new File(outputDirectory, "runmode.mapping");
            assertTrue(runmodeMapperFile.exists());
            assertTrue(runmodeMapperFile.isFile());
            Properties runModes = new Properties();
            try (FileInputStream input = new FileInputStream(runmodeMapperFile)) {
                runModes.load(input);
            }
            assertFalse(runModes.isEmpty());
            assertTrue(runModes.containsKey("(default)"));
            assertEquals("asd.retail.all.json", runModes.getProperty("(default)"));
            assertEquals("asd.retail.all-author.json", runModes.getProperty("author"));
            assertEquals("asd.retail.all-publish.json", runModes.getProperty("publish"));

            verifyContentPackage(new File(outputDirectory, "asd/Asd.Retail.config/0.0.1/Asd.Retail.config-0.0.1-cp2fm-converted.zip"),
                                "META-INF/vault/settings.xml",
                                "META-INF/vault/properties.xml",
                                "META-INF/vault/config.xml",
                                "META-INF/vault/filter.xml",
                                "jcr_root/apps/.content.xml");
            verifyContentPackage(new File(outputDirectory, "asd/sample/Asd.Retail.ui.content/0.0.1/Asd.Retail.ui.content-0.0.1-cp2fm-converted.zip"),
                                "META-INF/vault/settings.xml",
                                "META-INF/vault/properties.xml",
                                "META-INF/vault/config.xml",
                                "META-INF/vault/filter.xml",
                                "META-INF/vault/filter-plugin-generated.xml",
                                "jcr_root/content/asd/.content.xml",
                                "jcr_root/content/asd/resources.xml");
            verifyContentPackage(new File(outputDirectory, "asd/sample/asd.retail.apps/0.0.1/asd.retail.apps-0.0.1-cp2fm-converted.zip"),
                                "META-INF/vault/settings.xml",
                                "META-INF/vault/properties.xml",
                                "META-INF/vault/config.xml",
                                "META-INF/vault/filter.xml",
                                "META-INF/vault/filter-plugin-generated.xml");
            verifyContentPackage(new File(outputDirectory, "asd/sample/asd.retail.all/0.0.1/asd.retail.all-0.0.1-cp2fm-converted.zip"),
                                "META-INF/vault/settings.xml",
                                "META-INF/vault/properties.xml",
                                "META-INF/vault/config.xml",
                                "META-INF/vault/filter.xml");
        } finally {
            deleteDirTree(outputDirectory);
        }
    }

    @Test
    public void convertContentPackageDropContent() throws Exception {
        URL packageUrl = getClass().getResource("test-content-package.zip");
        File packageFile = FileUtils.toFile(packageUrl);

        File outputDirectory = new File(System.getProperty("java.io.tmpdir"), getClass().getName() + '_' + System.currentTimeMillis());

        try {

            converter.setFeaturesManager(new DefaultFeaturesManager(true, 5, outputDirectory, null, null, null, new DefaultAclManager()))
                    .setBundlesDeployer(new DefaultArtifactsDeployer(outputDirectory))
                    .setEmitter(DefaultPackagesEventsEmitter.open(outputDirectory))
                    .setDropContent(true)
                    .convert(packageFile);

            verifyFeatureFile(outputDirectory,
                            "asd.retail.all.json",
                            "asd.sample:asd.retail.all:slingosgifeature:0.0.1",
                            Arrays.asList("org.apache.felix:org.apache.felix.framework:6.0.1"),
                            Arrays.asList("org.apache.sling.commons.log.LogManager.factory.config~asd-retail"),
                            Arrays.asList("asd.sample:asd.retail.apps:zip:cp2fm-converted:0.0.1",
                                            "asd:Asd.Retail.config:zip:cp2fm-converted:0.0.1"));
            verifyFeatureFile(outputDirectory,
                            "asd.retail.all-author.json",
                            "asd.sample:asd.retail.all:slingosgifeature:author:0.0.1",
                            Arrays.asList("org.apache.sling:org.apache.sling.api:2.20.0"),
                            Collections.emptyList(),
                            Collections.emptyList());
            verifyFeatureFile(outputDirectory,
                            "asd.retail.all-publish.json",
                            "asd.sample:asd.retail.all:slingosgifeature:publish:0.0.1",
                            Arrays.asList("org.apache.sling:org.apache.sling.models.api:1.3.8"),
                            Arrays.asList("org.apache.sling.serviceusermapping.impl.ServiceUserMapperImpl.amended~asd-retail"),
                            Collections.emptyList());

            // verify the runmode.mapper integrity
            File runmodeMapperFile = new File(outputDirectory, "runmode.mapping");
            assertTrue(runmodeMapperFile.exists());
            assertTrue(runmodeMapperFile.isFile());
            Properties runModes = new Properties();
            try (FileInputStream input = new FileInputStream(runmodeMapperFile)) {
                runModes.load(input);
            }
            assertFalse(runModes.isEmpty());
            assertTrue(runModes.containsKey("(default)"));
            assertEquals("asd.retail.all.json", runModes.getProperty("(default)"));
            assertEquals("asd.retail.all-author.json", runModes.getProperty("author"));
            assertEquals("asd.retail.all-publish.json", runModes.getProperty("publish"));

            verifyContentPackage(new File(outputDirectory, "asd/Asd.Retail.config/0.0.1/Asd.Retail.config-0.0.1-cp2fm-converted.zip"),
                                "META-INF/vault/settings.xml",
                                "META-INF/vault/properties.xml",
                                "META-INF/vault/config.xml",
                                "META-INF/vault/filter.xml",
                                "jcr_root/apps/.content.xml");
            verifyContentPackage(new File(outputDirectory, "asd/sample/asd.retail.apps/0.0.1/asd.retail.apps-0.0.1-cp2fm-converted.zip"),
                                "META-INF/vault/settings.xml",
                                "META-INF/vault/properties.xml",
                                "META-INF/vault/config.xml",
                                "META-INF/vault/filter.xml",
                                "META-INF/vault/filter-plugin-generated.xml");
            // in contrast to previous test when dropping content packages the cases below would be filtered out and files wouldn'T be in cache
            assertFalse(new File(outputDirectory, "asd/sample/Asd.Retail.ui.content/0.0.1/Asd.Retail.ui.content-0.0.1-cp2fm-converted.zip").exists());
            assertFalse(new File(outputDirectory, "asd/sample/asd.retail.all/0.0.1/asd.retail.all-0.0.1-cp2fm-converted.zip").exists());

        } finally {
            deleteDirTree(outputDirectory);
        }
    }

    @Test
    public void convertContentPackageRemoveInstallHooks() throws Exception {
        URL packageUrl = getClass().getResource("test-with-install-hooks.zip");
        File packageFile = FileUtils.toFile(packageUrl);

        File outputDirectory = new File(System.getProperty("java.io.tmpdir"), getClass().getName() + '_' + System.currentTimeMillis());

        try {
            converter.setFeaturesManager(new DefaultFeaturesManager(true, 5, outputDirectory, null, null, null, new DefaultAclManager()))
                    .setBundlesDeployer(new DefaultArtifactsDeployer(outputDirectory))
                    .setEmitter(DefaultPackagesEventsEmitter.open(outputDirectory))
                    .setRemoveInstallHooks(true)
                    .convert(packageFile);

            File expectedPackage = new File(outputDirectory, "my_packages/tmp/0.0.0/tmp-0.0.0-cp2fm-converted.zip");
            verifyContentPackageEntryNames(expectedPackage,
                                "META-INF/vault/config.xml",
                                "META-INF/vault/definition/.content.xml",
                                "META-INF/vault/filter.xml",
                                "META-INF/vault/properties.xml",
                                "jcr_root/.content.xml",
                                "jcr_root/testroot/.content.xml");
            verifyPropertiesXmlEntry(expectedPackage, "!installhook.test1.class", "!installhook.test2.class");
        } finally {
            deleteDirTree(outputDirectory);
        }
    }

    @Test
    public void convertContentPackageKeepInstallHooks() throws Exception {
        URL packageUrl = getClass().getResource("test-with-install-hooks.zip");
        File packageFile = FileUtils.toFile(packageUrl);

        File outputDirectory = new File(System.getProperty("java.io.tmpdir"), getClass().getName() + '_' + System.currentTimeMillis());

        try {
            converter.setFeaturesManager(new DefaultFeaturesManager(true, 5, outputDirectory, null, null, null, new DefaultAclManager()))
                    .setBundlesDeployer(new DefaultArtifactsDeployer(outputDirectory))
                    .setEmitter(DefaultPackagesEventsEmitter.open(outputDirectory))
                    .convert(packageFile);

            File expectedPackage = new File(outputDirectory, "my_packages/tmp/0.0.0/tmp-0.0.0-cp2fm-converted.zip");
            verifyContentPackageEntryNames(expectedPackage,
                    "META-INF/vault/config.xml",
                    "META-INF/vault/definition/.content.xml",
                    "META-INF/vault/filter.xml",
                    "META-INF/vault/hooks/vault-hook-example-3.0.0.jar",
                    "META-INF/vault/properties.xml",
                    "jcr_root/.content.xml",
                    "jcr_root/testroot/.content.xml");
            verifyPropertiesXmlEntry(expectedPackage, "installhook.test1.class", "installhook.test2.class");
        } finally {
            deleteDirTree(outputDirectory);
        }
    }

    @Test
    public void testConvertContentPackageWithAPIRegion() throws Exception {
        URL cp = getClass().getResource("test_c-1.0.zip");
        File cpFile = new File(cp.getFile());
        File outDir = Files.createTempDirectory(getClass().getSimpleName()).toFile();

        try {
            DefaultFeaturesManager fm = new DefaultFeaturesManager(true, 5, outDir, null, null, null, new DefaultAclManager());
            fm.setAPIRegions(Arrays.asList("global", "foo.bar"));
            converter.setFeaturesManager(fm)
                     .setBundlesDeployer(new DefaultArtifactsDeployer(outDir))
                     .setEmitter(DefaultPackagesEventsEmitter.open(outDir))
                     .convert(cpFile);

            File featureFile = new File(outDir, "test_c.json");
            try (Reader reader = new FileReader(featureFile)) {
                Feature feature = FeatureJSONReader.read(reader, featureFile.getAbsolutePath());

                Extension apiRegions = feature.getExtensions().getByName("api-regions");
                assertEquals(ExtensionType.JSON, apiRegions.getType());
                String json = apiRegions.getJSON();
                JsonArray ja = Json.createReader(new StringReader(json)).readArray();
                assertEquals(2, ja.size());

                JsonObject globalJO = ja.getJsonObject(0);
                assertEquals("global", globalJO.getString("name"));
                JsonArray globalExports = globalJO.getJsonArray("exports");
                assertTrue(globalExports == null || globalExports.isEmpty());

                JsonObject foobarJO = ja.getJsonObject(1);
                assertEquals("foo.bar", foobarJO.getString("name"));
                JsonArray fooExports = foobarJO.getJsonArray("exports");
                assertTrue(fooExports == null || fooExports.isEmpty());
            }

        } finally {
            deleteDirTree(outDir);
        }
    }

    private void deleteDirTree(File dir) throws IOException {
        Path tempDir = dir.toPath();

        Files.walk(tempDir)
            .sorted(Comparator.reverseOrder())
            .map(Path::toFile)
            .forEach(File::delete);
    }

    private Feature getFeature(File outputDirectory, String name) throws Exception {
        File featureFile = new File(outputDirectory, name);
        assertTrue(featureFile + " was not correctly created", featureFile.exists());

        try (Reader reader = new FileReader(featureFile)) {
            return FeatureJSONReader.read(reader, featureFile.getAbsolutePath());
        }
    }

    private void verifyFeatureFile(File outputDirectory,
                                   String name,
                                   String expectedArtifactId,
                                   List<String> expectedArtifacts,
                                   List<String> expectedConfigurations,
                                   List<String> expectedContentPackagesExtensions) throws Exception {
        Feature feature = getFeature(outputDirectory, name);

        assertEquals(expectedArtifactId, feature.getId().toMvnId());

        for (String expectedArtifact : expectedArtifacts) {
            assertTrue(expectedArtifact + " not found in Feature " + expectedArtifactId, feature.getBundles().containsExact(ArtifactId.fromMvnId(expectedArtifact)));
            verifyInstalledArtifact(outputDirectory, expectedArtifact);
        }

        for (String expectedConfiguration : expectedConfigurations) {
            assertNotNull(expectedConfiguration + " not found in Feature " + expectedArtifactId, feature.getConfigurations().getConfiguration(expectedConfiguration));
        }

        if (expectedContentPackagesExtensions.size() > 0) {
        Artifacts contentPackages = feature.getExtensions().getByName("content-packages").getArtifacts();
        assertEquals(expectedContentPackagesExtensions.size(), contentPackages.size());

            for (String expectedContentPackagesExtension : expectedContentPackagesExtensions) {
                assertTrue(expectedContentPackagesExtension + " not found in Feature " + expectedArtifactId,
                    contentPackages.containsExact(ArtifactId.fromMvnId(expectedContentPackagesExtension)));
                verifyInstalledArtifact(outputDirectory, expectedContentPackagesExtension);
            }
        }
    }

    private void verifyInstalledArtifact(File outputDirectory, String coordinates) {
        ArtifactId bundleId = ArtifactId.fromMvnId(coordinates);

        StringTokenizer tokenizer = new StringTokenizer(bundleId.getGroupId(), ".");
        while (tokenizer.hasMoreTokens()) {
            outputDirectory = new File(outputDirectory, tokenizer.nextToken());
        }

        outputDirectory = new File(outputDirectory, bundleId.getArtifactId());
        outputDirectory = new File(outputDirectory, bundleId.getVersion());

        StringBuilder bundleFileName = new StringBuilder()
                                       .append(bundleId.getArtifactId())
                                       .append('-')
                                       .append(bundleId.getVersion());
        if (bundleId.getClassifier() != null) {
            bundleFileName.append('-').append(bundleId.getClassifier());
        }
        bundleFileName.append('.').append(bundleId.getType());

        File bundleFile = new File(outputDirectory, bundleFileName.toString());
        assertTrue("Bundle " + bundleFile + " does not exist", bundleFile.exists());

        File pomFile = new File(outputDirectory, String.format("%s-%s.pom", bundleId.getArtifactId(), bundleId.getVersion()));
        assertTrue("POM file " + pomFile + " does not exist", pomFile.exists());
    }

    private void verifyContentPackageEntryNames(File contentPackage, String...expectedEntryNames) throws Exception {
        try (ZipFile zipFile = new ZipFile(contentPackage)) {
            
            List<String> expectedEntryNamesList = Arrays.asList(expectedEntryNames);
            for (Enumeration<? extends ZipEntry> zipEntries = zipFile.entries(); zipEntries.hasMoreElements();) {
                ZipEntry zipEntry = zipEntries.nextElement();
                String entryName = zipEntry.getName();
                if (!entryName.endsWith("/")) {
                    assertTrue("ZipEntry with name " + entryName + " not expected", expectedEntryNamesList.contains(entryName));
                }
            }
            
        }
    }

    private void verifyContentPackage(File contentPackage, String...expectedEntries) throws Exception {
        try (ZipFile zipFile = new ZipFile(contentPackage)) {
            for (String expectedEntry : expectedEntries) {
                assertNotNull("Expected entry not found: " + expectedEntry + " in file " + contentPackage,
                              zipFile.getEntry(expectedEntry));
            }
        }
    }

    private void verifyPropertiesXmlEntry(File contentPackage, String... expectedPropertyKeys) throws InvalidPropertiesFormatException, IOException {
        try (ZipFile zipFile = new ZipFile(contentPackage)) {
            ZipEntry zipEntry = zipFile.getEntry(Constants.META_DIR + "/" + Constants.PROPERTIES_XML);
            assertNotNull("Package didn't contain properties.xml", zipEntry);
            try (InputStream inputStream = zipFile.getInputStream(zipEntry)) {
                Properties properties = new Properties();
                properties.loadFromXML(inputStream);
                for (String expectedPropertyKey : expectedPropertyKeys) {
                    if (expectedPropertyKey.startsWith("!")) {
                        String key = expectedPropertyKey.substring(1);
                        assertFalse("Properties.xml was not supposed to contain key " +  key + " but it does", properties.containsKey(key));
                    } else {
                        assertTrue("Properties.xml was supposed to contain key " +  expectedPropertyKey + " but it does not", properties.containsKey(expectedPropertyKey));
                    }
                }
            }
        }
    }

    @Test(expected = IllegalArgumentException.class)
    public void verifyFilteringOutUndesiredPackages() throws Exception {
        RegexBasedResourceFilter resourceFilter = new RegexBasedResourceFilter();
        resourceFilter.addFilteringPattern(".*\\/install(?!(\\.runMode1\\/|\\.runMode2\\/|\\/))(.*)(?=\\.zip$).*");
        converter.setResourceFilter(resourceFilter);

        URL packageUrl = getClass().getResource("test-content-package-unacceptable.zip");
        File packageFile = FileUtils.toFile(packageUrl);

        File outputDirectory = new File(System.getProperty("java.io.tmpdir"), getClass().getName() + '_' + System.currentTimeMillis());

        try {

            converter.setFeaturesManager(new DefaultFeaturesManager(true, 5, outputDirectory, null, null, null, new DefaultAclManager()))
                    .setBundlesDeployer(new DefaultArtifactsDeployer(outputDirectory))
                    .setEmitter(DefaultPackagesEventsEmitter.open(outputDirectory))
                    .convert(packageFile);
        } finally {
            deleteDirTree(outputDirectory);
        }
    }
    
    /** app package containing another app package must lead to an explicit dependency from  
     *  embedded to embedding package to reflect the implicit installation order via osgi Installer
    **/
    
    @Test
    public void verifyEmbeddedDependency() throws Exception {
        URL packageUrl = getClass().getResource("embedded.package.test-0.0.1.zip");
        File packageFile = FileUtils.toFile(packageUrl);

        File outputDirectory = new File(System.getProperty("java.io.tmpdir"), getClass().getName() + '_' + System.currentTimeMillis());

        try {

            converter.setFeaturesManager(new DefaultFeaturesManager(true, 5, outputDirectory, null, null, null, new DefaultAclManager()))
                    .setBundlesDeployer(new DefaultArtifactsDeployer(outputDirectory))
                    .setEmitter(DefaultPackagesEventsEmitter.open(outputDirectory))
                    .convert(packageFile);
            
            File contentPackage = new File(outputDirectory, "asd/sample/embedded.test.app/0.0.0/embedded.test.app-0.0.0-cp2fm-converted.zip");
            VaultPackage vaultPackage = new PackageManagerImpl().open(contentPackage);
            String dependencies = vaultPackage.getProperties().getProperty(PackageProperties.NAME_DEPENDENCIES);
            org.apache.jackrabbit.vault.packaging.Dependency dep = org.apache.jackrabbit.vault.packaging.Dependency.fromString(dependencies);
            PackageId targetId = PackageId.fromString("asd/sample:embedded.package.test:0.0.1-cp2fm-converted");
            assertTrue(dep.matches(targetId));
        } finally {
            deleteDirTree(outputDirectory);
        }
    }

    @Test(expected = IllegalStateException.class)
    public void doesNotAllowSameConfigurationPidForSameRunmode() throws Exception {
        addSamePidConfiguration(null, null);
    }

    @Test
    public void allowSameConfigurationPidForDifferentRunmode() throws Exception {
        addSamePidConfiguration(null, "test");
    }

    private void addSamePidConfiguration(String runmodeA, String runmodeB) throws Exception {
        File outputDirectory = new File(System.getProperty("java.io.tmpdir"), getClass().getName() + '_' + System.currentTimeMillis());
        try {
            URL packageUrl = getClass().getResource("test-content-package.zip");
            File packageFile = FileUtils.toFile(packageUrl);
    
            converter.setBundlesDeployer(new DefaultArtifactsDeployer(outputDirectory))
                     .setFeaturesManager(new DefaultFeaturesManager(DefaultFeaturesManager.ConfigurationHandling.STRICT, 5, outputDirectory, null, null, null, new DefaultAclManager()))
                     .setEmitter(DefaultPackagesEventsEmitter.open(outputDirectory))
                     .convert(packageFile);
    
            String pid = "this.is.just.a.pid";
            converter.getFeaturesManager().addConfiguration(runmodeA, pid, "/a", new Hashtable<String, Object>());
            converter.getFeaturesManager().addConfiguration(runmodeB, pid, "/b", new Hashtable<String, Object>());
    
        } finally {
            deleteDirTree(outputDirectory);
        }
    }

    @Test
    public void testSameConfigurationPidTwoDifferentPaths() throws Exception {
        File outputDirectory = new File(System.getProperty("java.io.tmpdir"), getClass().getName() + '_' + System.currentTimeMillis());
        try {
            URL packageUrl = getClass().getResource("test-content-package.zip");
            File packageFile = FileUtils.toFile(packageUrl);
    
            converter.setBundlesDeployer(new DefaultArtifactsDeployer(outputDirectory))
                     .setFeaturesManager(new DefaultFeaturesManager(false, 5, outputDirectory, null, null, null, new DefaultAclManager()))
                     .setEmitter(DefaultPackagesEventsEmitter.open(outputDirectory))
                     .convert(packageFile);
    
            String pid = "this.is.just.a.pid";
            converter.getFeaturesManager().addConfiguration(null, pid, "/apps/a/config/pid.json", new Hashtable<String, Object>(){{put("foo", "a");}});
            converter.getFeaturesManager().addConfiguration(null, pid, "/apps/b/config/pid.json", new Hashtable<String, Object>(){{put("foo", "b");}});
    
            Configuration c = converter.getFeaturesManager().getTargetFeature().getConfigurations().getConfiguration(pid);
            assertNotNull(c);
            assertEquals("a", c.getConfigurationProperties().get("foo"));
        } finally {
            deleteDirTree(outputDirectory);
        }
    }

    @Test
    public void testSameConfigurationPidThreeDifferentPaths() throws Exception {
        File outputDirectory = new File(System.getProperty("java.io.tmpdir"), getClass().getName() + '_' + System.currentTimeMillis());
        try {
            URL packageUrl = getClass().getResource("test-content-package.zip");
            File packageFile = FileUtils.toFile(packageUrl);
    
            converter.setBundlesDeployer(new DefaultArtifactsDeployer(outputDirectory))
                     .setFeaturesManager(new DefaultFeaturesManager(false, 5, outputDirectory, null, null, null, new DefaultAclManager()))
                     .setEmitter(DefaultPackagesEventsEmitter.open(outputDirectory))
                     .convert(packageFile);
    
            String pid = "this.is.just.a.pid";
            converter.getFeaturesManager().addConfiguration(null, pid, "/apps/b/config/pid.json", new Hashtable<String, Object>(){{put("foo", "b");}});
            converter.getFeaturesManager().addConfiguration(null, pid, "/apps/a/config/pid.json", new Hashtable<String, Object>(){{put("foo", "a");}});
            converter.getFeaturesManager().addConfiguration(null, pid, "/apps/c/config/pid.json", new Hashtable<String, Object>(){{put("foo", "c");}});
    
            Configuration c = converter.getFeaturesManager().getTargetFeature().getConfigurations().getConfiguration(pid);
            assertNotNull(c);
            assertEquals("a", c.getConfigurationProperties().get("foo"));
        } finally {
            deleteDirTree(outputDirectory);
        }
    }

    @Test
    public void testAPIRegionsWithRunmodes() throws Exception {
        URL cp = getClass().getResource("test-content-package.zip");
        File cpFile = new File(cp.getFile());
        File outDir = Files.createTempDirectory(getClass().getSimpleName()).toFile();

        try {
            converter.setBundlesDeployer(new DefaultArtifactsDeployer(outDir))
            .setFeaturesManager(new DefaultFeaturesManager(false, 5, outDir, null, null, null, new DefaultAclManager())
                    .setAPIRegions(Arrays.asList("a.b.c")))
            .setEmitter(DefaultPackagesEventsEmitter.open(outDir))
            .convert(cpFile);

            assertAPIRegion(new File(outDir, "asd.retail.all.json"), "a.b.c");
            assertAPIRegion(new File(outDir, "asd.retail.all-author.json"), "a.b.c");
            assertAPIRegion(new File(outDir, "asd.retail.all-publish.json"), "a.b.c");
        } finally {
            deleteDirTree(outDir);
        }

    }

    private void assertAPIRegion(File featureFile, String region) throws IOException, FileNotFoundException {
        try (Reader reader = new FileReader(featureFile)) {
            Feature feature = FeatureJSONReader.read(reader, featureFile.getAbsolutePath());

            Extension apiRegions = feature.getExtensions().getByName("api-regions");
            assertEquals(ExtensionType.JSON, apiRegions.getType());
            String json = apiRegions.getJSON();
            JsonArray ja = Json.createReader(new StringReader(json)).readArray();
            assertEquals(1, ja.size());

            JsonObject regionJO = ja.getJsonObject(0);
            assertEquals(region, regionJO.getString("name"));
            JsonArray exports = regionJO.getJsonArray("exports");
            assertTrue(exports == null || exports.isEmpty());
        }
    }

    @Test
    public void overrideFeatureId() throws Exception {
        URL packageUrl = getClass().getResource("test-content-package.zip");
        File packageFile = FileUtils.toFile(packageUrl);

        File outputDirectory = new File(System.getProperty("java.io.tmpdir"), getClass().getName() + '_' + System.currentTimeMillis());

        try {

            String overrideId = "${project.groupId}:${project.artifactId}:slingosgifeature:asd.test.all-1.0.0:${project.version}";
            converter.setFeaturesManager(new DefaultFeaturesManager(true, 5, outputDirectory, overrideId, null, null, new DefaultAclManager()))
                    .setBundlesDeployer(new DefaultArtifactsDeployer(outputDirectory))
                    .setEmitter(DefaultPackagesEventsEmitter.open(outputDirectory))
                    .convert(packageFile);

            verifyFeatureFile(outputDirectory,
                            "asd.retail.all.json",
                            "${project.groupId}:${project.artifactId}:slingosgifeature:asd.test.all-1.0.0:${project.version}",
                            Arrays.asList("org.apache.felix:org.apache.felix.framework:6.0.1"),
                            Arrays.asList("org.apache.sling.commons.log.LogManager.factory.config~asd-retail"),
                            Arrays.asList("asd.sample:asd.retail.apps:zip:cp2fm-converted:0.0.1",
                                            "asd.sample:Asd.Retail.ui.content:zip:cp2fm-converted:0.0.1",
                                            "asd:Asd.Retail.config:zip:cp2fm-converted:0.0.1",
                                            "asd.sample:asd.retail.all:zip:cp2fm-converted:0.0.1"));
            verifyFeatureFile(outputDirectory,
                            "asd.retail.all-author.json",
                            "${project.groupId}:${project.artifactId}:slingosgifeature:asd.test.all-1.0.0-author:${project.version}",
                            Arrays.asList("org.apache.sling:org.apache.sling.api:2.20.0"),
                            Collections.emptyList(),
                            Collections.emptyList());
            verifyFeatureFile(outputDirectory,
                            "asd.retail.all-publish.json",
                            "${project.groupId}:${project.artifactId}:slingosgifeature:asd.test.all-1.0.0-publish:${project.version}",
                            Arrays.asList("org.apache.sling:org.apache.sling.models.api:1.3.8"),
                            Arrays.asList("org.apache.sling.serviceusermapping.impl.ServiceUserMapperImpl.amended~asd-retail"),
                            Collections.emptyList());

            verifyContentPackage(new File(outputDirectory, "asd/sample/asd.retail.all/0.0.1/asd.retail.all-0.0.1-cp2fm-converted.zip"),
                                "META-INF/vault/properties.xml",
                                "META-INF/vault/config.xml",
                                "META-INF/vault/settings.xml",
                                "META-INF/vault/filter.xml");
        } finally {
            deleteDirTree(outputDirectory);
        }
    }

    @Test
    public void testPackageOrdering() throws Exception {
        File[] contentPackages = load(TEST_PACKAGES_INPUT);

        Collection<VaultPackage> ordered = converter.firstPass(contentPackages);

        Iterator<VaultPackage> fileIt = ordered.iterator();
        for (String expected : TEST_PACKAGES_OUTPUT) {
            VaultPackage next = fileIt.next();
            assertEquals(expected, next.getId().toString());
        }
    }

    @Test(expected = CyclicDependencyException.class)
    public void testDependencyCycle() throws Exception {
        File[] contentPackages = load(TEST_PACKAGES_CYCLIC_DEPENDENCY);
        converter.firstPass(contentPackages);
    }

    @Test
    public void includeLatestUpdatedContentPackagesOnly() throws Exception {
        File[] contentPackages = load("test-content-package.zip", "test-content-package-2.zip");
        converter.firstPass(contentPackages);

        assertTrue(converter.isSubContentPackageIncluded("/jcr_root/etc/packages/asd/test-content-0.2.zip"));
        assertFalse(converter.isSubContentPackageIncluded("/jcr_root/etc/packages/asd/test-content.zip"));
    }

    @Test
    public void verifyRepoinitContainsNodetypesRegistration() throws Exception {
        File[] contentPackages = load(TEST_PACKAGES_INPUT[1]);

        File outputDirectory = new File(System.getProperty("java.io.tmpdir"), getClass().getName() + '_' + System.currentTimeMillis());

        try {

            converter.setFeaturesManager(new DefaultFeaturesManager(true, 5, outputDirectory, null, null, null, new DefaultAclManager()))
                    .setBundlesDeployer(new DefaultArtifactsDeployer(outputDirectory))
                    .setEmitter(DefaultPackagesEventsEmitter.open(outputDirectory))
                    .convert(contentPackages[0]);

            File featureFile = new File(outputDirectory, "test_a.json");
            try (Reader reader = new FileReader(featureFile)) {
                Feature feature = FeatureJSONReader.read(reader, featureFile.getAbsolutePath());

                Extension repoinitExtension = feature.getExtensions().getByName("repoinit");
                assertNotNull(repoinitExtension);

                String expected = "register nodetypes\n" +
                        "<<===\n" +
                        "<< <'sling'='http://sling.apache.org/jcr/sling/1.0'>\n" +
                        "<< <'nt'='http://www.jcp.org/jcr/nt/1.0'>\n" + 
                        "<< <'rep'='internal'>\n" + 
                        "\n" + 
                        "<< [sling:Folder] > nt:folder\n" +
                        "<<   - * (undefined) multiple\n" +
                        "<<   - * (undefined)\n" +
                        "<<   + * (nt:base) = sling:Folder version\n" + 
                        "\n" +
                        "<< [rep:RepoAccessControllable]\n" +
                        "<<   mixin\n"  +
                        "<<   + rep:repoPolicy (rep:Policy) protected ignore\n" +
                        "===>>\n";
                String actual = repoinitExtension.getText();
                assertEquals(expected, actual);
            }
        } finally {
            deleteDirTree(outputDirectory);
        }
    }

    // see SLING-8649
    @Test
    public void filteredOutContentPackagesAreExcludedDependencies() throws Exception {
        File[] contentPackages = load("test_dep_a-1.0.zip", "test_dep_b-1.0.zip");

        // input: c <- a <- b
        // expected output: c <- a

        File outputDirectory = new File(System.getProperty("java.io.tmpdir"), getClass().getName() + '_' + System.currentTimeMillis());
        try {
            converter.setFeaturesManager(new DefaultFeaturesManager(true, 5, outputDirectory, null, null, null, new DefaultAclManager()))
                    .setDropContent(true)
                    .setBundlesDeployer(new DefaultArtifactsDeployer(outputDirectory))
                    .setEmitter(DefaultPackagesEventsEmitter.open(outputDirectory))
                    .convert(contentPackages);

            Feature a = getFeature(outputDirectory, "test_a.json");
            assertNull(a.getExtensions().getByName("content-packages"));

            Feature b = getFeature(outputDirectory, "test_b.json");
            assertNotNull(b.getExtensions().getByName("content-packages"));
            Artifacts artifacts = b.getExtensions().getByName("content-packages").getArtifacts();
            assertFalse(artifacts.isEmpty());
            assertEquals("my_packages:test_b:zip:cp2fm-converted:1.0", artifacts.iterator().next().getId().toString());

            File contentPackage = new File(outputDirectory, "my_packages/test_b/1.0/test_b-1.0-cp2fm-converted.zip");
            VaultPackage vaultPackage = new PackageManagerImpl().open(contentPackage);
            String dependencies = vaultPackage.getProperties().getProperty(PackageProperties.NAME_DEPENDENCIES);
            assertEquals("my_packages:test_c", dependencies);
        }
        finally {
            deleteDirTree(outputDirectory);
        }
    }

    private File[] load(String...resources) {
        File[] loadedResources = new File[resources.length];

        for (int i = 0; i < resources.length; i++) {
            String resourceName = resources[i];
            URL resourceUrl = getClass().getResource(resourceName);
            loadedResources[i] = FileUtils.toFile(resourceUrl);
        }

        return loadedResources;
    }

}
