/*
 * 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 java.util.Objects.requireNonNull;
import static org.apache.sling.feature.cpconverter.vltpkg.VaultPackageUtils.detectPackageType;
import static org.apache.sling.feature.cpconverter.vltpkg.VaultPackageUtils.getDependencies;

import java.io.File;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedHashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.regex.Pattern;

import org.apache.jackrabbit.vault.fs.io.Archive;
import org.apache.jackrabbit.vault.fs.io.Archive.Entry;
import org.apache.jackrabbit.vault.packaging.CyclicDependencyException;
import org.apache.jackrabbit.vault.packaging.Dependency;
import org.apache.jackrabbit.vault.packaging.PackageId;
import org.apache.jackrabbit.vault.packaging.PackageProperties;
import org.apache.jackrabbit.vault.packaging.PackageType;
import org.apache.jackrabbit.vault.packaging.VaultPackage;
import org.apache.sling.feature.ArtifactId;
import org.apache.sling.feature.cpconverter.accesscontrol.AclManager;
import org.apache.sling.feature.cpconverter.artifacts.ArtifactsDeployer;
import org.apache.sling.feature.cpconverter.artifacts.FileArtifactWriter;
import org.apache.sling.feature.cpconverter.features.FeaturesManager;
import org.apache.sling.feature.cpconverter.filtering.ResourceFilter;
import org.apache.sling.feature.cpconverter.handlers.EntryHandler;
import org.apache.sling.feature.cpconverter.handlers.EntryHandlersManager;
import org.apache.sling.feature.cpconverter.handlers.NodeTypesEntryHandler;
import org.apache.sling.feature.cpconverter.vltpkg.BaseVaultPackageScanner;
import org.apache.sling.feature.cpconverter.vltpkg.PackagesEventsEmitter;
import org.apache.sling.feature.cpconverter.vltpkg.RecollectorVaultPackageScanner;
import org.apache.sling.feature.cpconverter.vltpkg.VaultPackageAssembler;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

public class ContentPackage2FeatureModelConverter extends BaseVaultPackageScanner {

    public static final String ZIP_TYPE = "zip";

    public static final String PACKAGE_CLASSIFIER = "cp2fm-converted";

    private static final String DEFEAULT_VERSION = "0.0.0";

    private final Map<PackageId, String> subContentPackages = new HashMap<>();

    private final List<VaultPackageAssembler> assemblers = new LinkedList<>();

    private final Map<PackageId, Set<Dependency>> mutableContentsIds = new LinkedHashMap<>();

    private EntryHandlersManager handlersManager;

    private AclManager aclManager;

    private FeaturesManager featuresManager;

    private ResourceFilter resourceFilter;

    private ArtifactsDeployer artifactsDeployer;

    private VaultPackageAssembler mainPackageAssembler;

    private final RecollectorVaultPackageScanner recollectorVaultPackageScanner;

    private PackagesEventsEmitter emitter;

    private boolean failOnMixedPackages = false;

    private boolean dropContent = false;

    public ContentPackage2FeatureModelConverter() {
        this(false);
    }

    public ContentPackage2FeatureModelConverter(boolean strictValidation) {
        super(strictValidation);
        this.recollectorVaultPackageScanner = new RecollectorVaultPackageScanner(this, this.packageManager, strictValidation, subContentPackages);
    }

    public @NotNull ContentPackage2FeatureModelConverter setEntryHandlersManager(@Nullable EntryHandlersManager handlersManager) {
        this.handlersManager = handlersManager;
        return this;
    }

    public @Nullable FeaturesManager getFeaturesManager() {
        return featuresManager;
    }

    public @NotNull ContentPackage2FeatureModelConverter setFeaturesManager(@Nullable FeaturesManager featuresManager) {
        this.featuresManager = featuresManager;
        return this;
    }

    public @NotNull ContentPackage2FeatureModelConverter setResourceFilter(@Nullable ResourceFilter resourceFilter) {
        this.resourceFilter = resourceFilter;
        return this;
    }

    public @Nullable ArtifactsDeployer getArtifactsDeployer() {
        return artifactsDeployer;
    }

    public @NotNull ContentPackage2FeatureModelConverter setBundlesDeployer(@Nullable ArtifactsDeployer bundlesDeployer) {
        this.artifactsDeployer = bundlesDeployer;
        return this;
    }

    public @Nullable AclManager getAclManager() {
        return aclManager;
    }

    public @NotNull ContentPackage2FeatureModelConverter setAclManager(@Nullable AclManager aclManager) {
        this.aclManager = aclManager;
        return this;
    }

    public @Nullable VaultPackageAssembler getMainPackageAssembler() {
        return mainPackageAssembler;
    }

    public @NotNull ContentPackage2FeatureModelConverter setEmitter(@Nullable PackagesEventsEmitter emitter) {
        this.emitter = emitter;
        return this;
    }
    
    public @NotNull ContentPackage2FeatureModelConverter setDropContent(boolean dropContent) {
        this.dropContent = dropContent;
        return this;
    }

    public @NotNull ContentPackage2FeatureModelConverter setFailOnMixedPackages(boolean failOnMixedPackages) {
        this.failOnMixedPackages = failOnMixedPackages;
        return this;
    }

    public void convert(@NotNull File...contentPackages) throws Exception {
        requireNonNull(contentPackages , "Null content-package(s) can not be converted.");
        secondPass(firstPass(contentPackages));
    }

    protected @NotNull Collection<VaultPackage> firstPass(@NotNull File...contentPackages) throws Exception {
        Map<PackageId, VaultPackage> idFileMap = new LinkedHashMap<>();
        Map<PackageId, VaultPackage> idPackageMapping = new ConcurrentHashMap<>();

        for (File contentPackage : contentPackages) {
            requireNonNull(contentPackage, "Null content-package can not be converted.");

            if (!contentPackage.exists() || !contentPackage.isFile()) {
                throw new IllegalArgumentException("File " + contentPackage + " does not exist or it is a directory");
            }

            logger.info("Reading content-package '{}'...", contentPackage);

            VaultPackage pack = open(contentPackage);
            idPackageMapping.put(pack.getId(), pack);

            // analyze sub-content packages in order to filter out
            // possible outdated conflicting packages
            recollectorVaultPackageScanner.traverse(pack);

            logger.info("content-package '{}' successfully read!", contentPackage);
        }

        logger.info("Ordering input content-package(s) {}...", idPackageMapping.keySet());

        for (VaultPackage pack : idPackageMapping.values()) {
            orderDependencies(idFileMap, idPackageMapping, pack, new HashSet<>());
        }

        logger.info("New content-package(s) order: {}", idFileMap.keySet());

        return idFileMap.values();
    }

    protected void secondPass(@NotNull Collection<VaultPackage> orderedContentPackages) throws Exception {
        emitter.start();

        for (VaultPackage vaultPackage : orderedContentPackages) {
            try {
                emitter.startPackage(vaultPackage);
                mainPackageAssembler = VaultPackageAssembler.create(vaultPackage);
                assemblers.add(mainPackageAssembler);

                ArtifactId mvnPackageId = toArtifactId(vaultPackage);

                featuresManager.init(mvnPackageId.getGroupId(), mvnPackageId.getArtifactId(), mvnPackageId.getVersion());

                logger.info("Converting content-package '{}'...", vaultPackage.getId());

                traverse(vaultPackage);

                // make sure

                mainPackageAssembler.updateDependencies(mutableContentsIds);

                // attach all unmatched resources as new content-package

                File contentPackageArchive = mainPackageAssembler.createPackage();

                // deploy the new zip content-package to the local mvn bundles dir

                processContentPackageArchive(contentPackageArchive, null, mvnPackageId, vaultPackage.getId());

                // finally serialize the Feature Model(s) file(s)

                aclManager.addRepoinitExtension(assemblers, featuresManager);

                logger.info("Conversion complete!");

                featuresManager.serialize();
                emitter.endPackage();
            } finally {
                aclManager.reset();
                assemblers.clear();

                try {
                    vaultPackage.close();
                } catch (Exception e) {
                    // close quietly
                }
            }
        }

        mutableContentsIds.clear();

        emitter.end();
    }

    private void orderDependencies(@NotNull Map<PackageId, VaultPackage> idFileMap,
                                   @NotNull Map<PackageId, VaultPackage> idPackageMapping,
                                   @NotNull VaultPackage pack,
                                   @NotNull Set<PackageId> visited) throws CyclicDependencyException {
        if (!visited.add(pack.getId())) {
            throw new CyclicDependencyException("Cyclic dependency detected, " + pack.getId() + " was previously visited already");
        }

        for (Dependency dep : pack.getDependencies()) {
            for (java.util.Map.Entry<PackageId, VaultPackage> entry : idPackageMapping.entrySet()) {
                if (dep.matches(entry.getKey())) {
                    orderDependencies(idFileMap, idPackageMapping, entry.getValue(), visited);
                    break;
                }
            }
        }

        idFileMap.put(pack.getId(), pack);
        idPackageMapping.remove(pack.getId());
    }

    public void processSubPackage(@NotNull String path, @Nullable String runMode, @NotNull VaultPackage vaultPackage, boolean isEmbeddedPackage) throws Exception {
        requireNonNull(path, "Impossible to process a null vault package");
        requireNonNull(vaultPackage, "Impossible to process a null vault package");

        if (!isSubContentPackageIncluded(path)) {
            logger.info("Sub content-package {} is filtered out, so it won't be processed.", path);
            return;
        }

        emitter.startSubPackage(path, vaultPackage);

        PackageId originalPackageId = vaultPackage.getId();
        ArtifactId mvnPackageId = toArtifactId(vaultPackage);
        VaultPackageAssembler clonedPackage = VaultPackageAssembler.create(vaultPackage);

        // Please note: THIS IS A HACK to meet the new requirement without drastically change the original design
        // temporary swap the main handler to collect stuff
        VaultPackageAssembler handler = mainPackageAssembler;
        assemblers.add(handler);
        Properties parentProps = handler.getPackageProperties();
        boolean isContainerPackage = PackageType.CONTAINER.equals(parentProps.get(PackageProperties.NAME_PACKAGE_TYPE));
        mainPackageAssembler = clonedPackage;

        // scan the detected package, first
        traverse(vaultPackage);

        clonedPackage.updateDependencies(mutableContentsIds);
        
        //set dependency to parent package if the parent package is an application package & subpackage is embedded
        if (isEmbeddedPackage && !isContainerPackage) {
            PackageId parentId = new PackageId((String)parentProps.get(PackageProperties.NAME_GROUP), 
                                                (String)parentProps.get(PackageProperties.NAME_NAME),
                                                (String)parentProps.get(PackageProperties.NAME_VERSION));
            clonedPackage.addDependency(new Dependency(parentId));
        }

        File contentPackageArchive = clonedPackage.createPackage();

        // deploy the new content-package to the local mvn bundles dir and attach it to the feature
        processContentPackageArchive(contentPackageArchive, runMode, mvnPackageId, originalPackageId);

        // restore the previous assembler
        mainPackageAssembler = handler;

        emitter.endSubPackage();
    }

    private void processContentPackageArchive(@NotNull File contentPackageArchive,
                                              @Nullable String runMode,
                                              @NotNull ArtifactId mvnPackageId,
                                              @NotNull PackageId originalPackageId) throws Exception {
        try (VaultPackage vaultPackage = open(contentPackageArchive)) {
            PackageType packageType = detectPackageType(vaultPackage);

            // SLING-8608 - Fail the conversion if the resulting attached content-package is MIXED type
            if (PackageType.MIXED == packageType && failOnMixedPackages) {
                throw new Exception("Generated content-package '"
                                    + originalPackageId
                                    + "' located in file "
                                    + contentPackageArchive
                                    + " is of MIXED type");
            }

            // don't deploy & add content-packages of type content to featuremodel if dropContent is set
            if (PackageType.CONTENT != packageType || !dropContent) {
                // deploy the new content-package to the local mvn bundles dir and attach it to the feature
                artifactsDeployer.deploy(new FileArtifactWriter(contentPackageArchive), mvnPackageId);
                featuresManager.addArtifact(runMode, mvnPackageId);
            } else {
                mutableContentsIds.put(originalPackageId, getDependencies(vaultPackage));
                logger.info("Dropping package of PackageType.CONTENT {} (content-package id: {})",
                            mvnPackageId.getArtifactId(), originalPackageId);
            }
        }
    }

    protected boolean isSubContentPackageIncluded(@NotNull String path) {
        return subContentPackages.containsValue(path);
    }

    @Override
    protected void onFile(@NotNull String entryPath, @NotNull Archive archive, @NotNull Entry entry) throws Exception {
        if (resourceFilter != null && resourceFilter.isFilteredOut(entryPath)) {
            throw new IllegalArgumentException("Path '"
                                               + entryPath
                                               + "' in archive "
                                               + archive.getMetaInf().getProperties()
                                               + " not allowed by user configuration, please check configured filtering patterns");
        }

        EntryHandler entryHandler = handlersManager.getEntryHandlerByEntryPath(entryPath);
        if (entryHandler == null) {
            entryHandler = mainPackageAssembler;
        }

        entryHandler.handle(entryPath, archive, entry, this);
    }

    private static @NotNull ArtifactId toArtifactId(@NotNull VaultPackage vaultPackage) {
        PackageId packageId = vaultPackage.getId();
        String groupId = requireNonNull(packageId.getGroup(),
            PackageProperties.NAME_GROUP
                + " property not found in content-package "
                + vaultPackage
                + ", please check META-INF/vault/properties.xml").replace('/', '.');
        // Replace any space with an underscore to adhere to Maven Group Id specification
        groupId = groupId.replaceAll(" ", "_");

        String artifactid = requireNonNull(packageId.getName(),
            PackageProperties.NAME_NAME
                + " property not found in content-package "
                + vaultPackage
                + ", please check META-INF/vault/properties.xml");
        // Replace any space with an underscore to adhere to Maven Artifact Id specification
        artifactid = artifactid.replaceAll(" ", "_");

        String version = packageId.getVersionString();
        if (version == null || version.isEmpty()) {
            version = DEFEAULT_VERSION;
        }

        return new ArtifactId(groupId, artifactid, version, PACKAGE_CLASSIFIER, ZIP_TYPE);
    }

    @Override
    protected void addCdnPattern(@NotNull Pattern cndPattern) {
        handlersManager.addEntryHandler(new NodeTypesEntryHandler(cndPattern));
    }

}
