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

import org.apache.maven.artifact.Artifact;
import org.apache.maven.artifact.ArtifactUtils;
import org.apache.maven.artifact.DefaultArtifact;
import org.apache.maven.artifact.handler.DefaultArtifactHandler;
import org.apache.maven.plugin.MojoExecutionException;
import org.apache.maven.plugin.MojoFailureException;
import org.apache.maven.plugins.annotations.Mojo;
import org.apache.maven.plugins.annotations.Parameter;
import org.apache.maven.project.ProjectBuildingRequest;
import org.apache.maven.shared.transfer.artifact.install.ArtifactInstallerException;
import org.apache.sling.feature.cpconverter.ContentPackage2FeatureModelConverter;
import org.apache.sling.feature.cpconverter.acl.DefaultAclManager;
import org.apache.sling.feature.cpconverter.artifacts.DefaultArtifactsDeployer;
import org.apache.sling.feature.cpconverter.features.DefaultFeaturesManager;
import org.apache.sling.feature.cpconverter.handlers.DefaultEntryHandlersManager;
import org.apache.sling.feature.cpconverter.vltpkg.DefaultPackagesEventsEmitter;

import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.StandardCopyOption;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import static org.apache.sling.feature.cpconverter.ContentPackage2FeatureModelConverter.PACKAGE_CLASSIFIER;
import static org.apache.sling.feature.cpconverter.ContentPackage2FeatureModelConverter.ZIP_TYPE;

/**
 * Converts the given Content Packages into Feature Models
 * and places the converted Content Package into the local
 * Maven Repository
 */
@Mojo(
    name = "convert-cp",
    requiresProject = true,
    threadSafe = true
)
public final class ConvertCPMojo
    extends AbstractBaseMojo
{
    public static final String CFG_STRICT_VALIDATION = "strictValidation";

    public static final String CFG_MERGE_CONFIGURATIONS = "mergeConfigurations";

    public static final String CFG_BUNDLE_START_ORDER = "bundleStartOrder";

    public static final String CFG_ARTIFACT_ID_OVERRIDE = "artifactIdOverride";

    public static final String CFG_INSTALL_CONVERTED_PACKAGE = "installConvertedContentPackage";

    public static final String CFG_FM_OUTPUT_DIRECTORY = "featureModelsOutputDirectory";

    public static final String CFG_CONVERTED_CP_OUTPUT_DIRECTORY = "convertedContentPackageOutputDirectory";

    public static final String CFG_CONVERTED_CP_FM_PREFIX = "fmPrefix";

    public static final String CFG_SYSTEM_PROPERTIES = "cpSystemProperties";

    public static final String CFG_CONTENT_PACKAGES = "packages";

    public static final String CFG_IS_CONTENT_PACKAGE = "isContentPackage";

    public static final boolean DEFAULT_STRING_VALIDATION = false;

    public static final boolean DEFAULT_MERGE_CONFIGURATIONS = false;

    public static final int DEFAULT_BUNDLE_START_ORDER = 20;

    public static final boolean DEFAULT_INSTALL_CONVERTED_PACKAGE = true;

    public static final String DEFAULT_CONVERTED_CP_OUTPUT_DIRECTORY = "${project.build.directory}/cp-conversion";

    public static final String DEFAULT_FM_OUTPUT_DIRECTORY = DEFAULT_CONVERTED_CP_OUTPUT_DIRECTORY + "/fm.out";

    public static final boolean DEFAULT_IS_CONTENT_PACKAGE = false;

    /**
     * If set to {@code true} the Content Package is strictly validated.
     */
    @Parameter(property = CFG_STRICT_VALIDATION, defaultValue = DEFAULT_STRING_VALIDATION + "")
    private boolean strictValidation;

    //AS TODO: Is that applicable to a single CP ?
    /**
     * If set to {@code true} the OSGi Configurations with same PID are merged.
     */
    @Parameter(property = CFG_MERGE_CONFIGURATIONS, defaultValue = DEFAULT_MERGE_CONFIGURATIONS + "")
    private boolean mergeConfigurations;

    /**
     * If set to {@code true} the Content Package is strictly validated.
     */
    @Parameter(property = CFG_BUNDLE_START_ORDER, defaultValue = DEFAULT_BUNDLE_START_ORDER + "")
    private int bundleStartOrder;

    /**
     * If set to {@code true} the Content Package is strictly validated.
     */
    @Parameter(property = CFG_ARTIFACT_ID_OVERRIDE)
    private String artifactIdOverride;

    /**
     * Target directory for the converted Content Package Feature Model file
     */
    @Parameter(property = CFG_FM_OUTPUT_DIRECTORY, defaultValue = DEFAULT_FM_OUTPUT_DIRECTORY)
    private File fmOutput;

    /**
     * Target directory for the Converted Content Package file
     */
    @Parameter(property = CFG_CONVERTED_CP_OUTPUT_DIRECTORY, defaultValue = DEFAULT_CONVERTED_CP_OUTPUT_DIRECTORY)
    private File convertedCPOutput;

    /**
     * If set to {@code true} the converted Content Package will be installed in the local Maven Repository
     */
    @Parameter(property = CFG_INSTALL_CONVERTED_PACKAGE, defaultValue = DEFAULT_INSTALL_CONVERTED_PACKAGE + "")
    private boolean installConvertedCP;

    /**
     * System Properties to hand over to the Content Package Converter
     */
    @Parameter(property = CFG_CONVERTED_CP_FM_PREFIX)
    private String fmPrefix;

    /**
     * System Properties to hand over to the Content Package Converter
     */
    @Parameter(property = CFG_SYSTEM_PROPERTIES)
    private List<String> systemProperties;

    /**
     * List of Content Packages to be converted
     */
    @Parameter(property = CFG_CONTENT_PACKAGES)
    private List<ContentPackage> contentPackages;

    /**
     * If set to {@code true} the module is handled as Content Package
     */
    @Parameter(property = CFG_IS_CONTENT_PACKAGE, defaultValue = DEFAULT_IS_CONTENT_PACKAGE + "")
    private boolean isContentPackage;

    @Override
    public void execute() throws MojoExecutionException, MojoFailureException {
        // Un-encode a given Artifact Override Id
        if(artifactIdOverride != null) {
            String old = artifactIdOverride;
            artifactIdOverride = artifactIdOverride.replaceAll("\\$\\{\\{", "\\$\\{");
            artifactIdOverride = artifactIdOverride.replaceAll("}}", "}");
            getLog().info("Replaced Old Artifact Id Override: '" + old + "', with new one: '" + artifactIdOverride + "'");
        }
        // Parse the System Properties if provided
        Map<String,String> properties = new HashMap<>();
        if(systemProperties != null) {
            for(String systemProperty: systemProperties) {
                if(systemProperty != null) {
                    int index = systemProperty.indexOf("=");
                    if(index > 0 && index < systemProperty.length() - 1) {
                        String key = systemProperty.substring(0, index);
                        String value = systemProperty.substring(index + 1);
                        properties.put(key, value);
                    }
                }
            }
        }
        try {
            ContentPackage2FeatureModelConverter converter = new ContentPackage2FeatureModelConverter(strictValidation)
                .setFeaturesManager(
                    new DefaultFeaturesManager(
                        mergeConfigurations,
                        bundleStartOrder,
                        fmOutput,
                        artifactIdOverride,
                        fmPrefix,
                        properties
                    )
                )
                .setBundlesDeployer(
                    new DefaultArtifactsDeployer(
                        convertedCPOutput
                    )
                )
                .setEntryHandlersManager(
                    new DefaultEntryHandlersManager()
                )
                .setAclManager(
                    new DefaultAclManager()
                )
                .setEmitter(DefaultPackagesEventsEmitter.open(fmOutput));

            if(contentPackages == null || contentPackages.isEmpty()) {
                getLog().info("Project Artifact File: " + project.getArtifact());
                String targetPath = project.getModel().getBuild().getDirectory() + "/"
                    + project.getModel().getBuild().getFinalName()
                    + "." + ZIP_TYPE;
                File targetFile = new File(targetPath);
                if (targetFile.exists() && targetFile.isFile() && targetFile.canRead()) {
                    converter.convert(project.getArtifact().getFile());
                } else {
                    getLog().error("Artifact is not found: " + targetPath);
                }
            } else {
                for(ContentPackage contentPackage: contentPackages) {
                    getLog().info("Content Package Artifact File: " + contentPackage.toString() + ", is module CP: " + isContentPackage);
                    contentPackage.setExcludeTransitive(true);
                    contentPackage.setModuleIsContentPackage(isContentPackage);
                    final Collection<Artifact> artifacts = contentPackage.getMatchingArtifacts(project);
                    if (artifacts.isEmpty()) {
                        getLog().warn("No matching artifacts for " + contentPackage);
                        continue;
                    }
                    getLog().info("Target Convert CP of --- " + contentPackage + " ---");
                    for (final Artifact artifact : artifacts) {
                        final File source = artifact.getFile();
                        getLog().info("Artifact: '" + artifact + "', source file: '" + source + "'");
                        if (source.exists() && source.isFile() && source.canRead()) {
                            converter.convert(source);
                            Artifact convertedPackage = new DefaultArtifact(
                                artifact.getGroupId(), artifact.getArtifactId(), artifact.getVersion(),
                                "compile", ZIP_TYPE, PACKAGE_CLASSIFIER, artifactHandlerManager.getArtifactHandler(ZIP_TYPE)
                            );
//                            installConvertedCP(convertedPackage);
                        } else {
                            getLog().error("Artifact is not found: " + artifact);
                        }
                    }
                }
            }
            installGeneratedArtifacts();
        } catch (Throwable t) {
            throw new MojoExecutionException("Content Package Converter Exception", t);
        }

    }

    /**
     * For now this is a hack to update the local Maven Repo (.m2/repository) correctly
     * bypassing the Maven Installer as this is giving us grief
     */
    private void installGeneratedArtifacts() {
        if(installConvertedCP) {
            File userHome = new File(System.getProperty("user.home"));
            if(userHome.isDirectory()) {
                File destFolder = new File(userHome, ".m2/repository");
                if(destFolder.isDirectory()) {
                    copyFiles(convertedCPOutput, destFolder);
                    if(isContentPackage) {
                        installFMDescriptor(project.getArtifact());
                    }
                }
            }
        }
    }

    /**
     * Copies the local generated Maven Artifacts into the local Maven Repo
     * recursively one folder at the time.
     * Folder are created on the local Maven Repo if not found, missing files
     * are copied over but only CP2FM Converted CP files are replaced on the
     * target folders
     *
     * @param source Folder with the source files / folders
     * @param destination Destination folder (inside the local Maven repo). This is the corresponding folder to the source
     */
    private void copyFiles(File source, File destination) {
        for(File file: source.listFiles()) {
            String name = file.getName();
            if(file.isDirectory()) {
                File newDest = new File(destination, name);
                if(!newDest.exists()) {
                    newDest.mkdirs();
                }
                if(newDest.isDirectory()) {
                    copyFiles(file, newDest);
                } else {
                    getLog().warn("Source File: '" + file.getAbsolutePath() + "' is a folder but its counterpart is a file: " + newDest.getAbsolutePath());
                }
            } else {
                File newDest = new File(destination, name);
                if(!newDest.exists()) {
                    // Copy File over
                    try {
                        Files.copy(file.toPath(), newDest.toPath(), StandardCopyOption.COPY_ATTRIBUTES);
                    } catch (IOException e) {
                        getLog().warn("Failed to copy File: '" + file.getAbsolutePath() + "' to File: " + newDest.getAbsolutePath(), e);
                    }
                } else {
                    // We only overwrite converted files
                    if(name.endsWith(PACKAGE_CLASSIFIER + "." + ZIP_TYPE)) {
                        // Copy File over
                        try {
                            Files.copy(file.toPath(), newDest.toPath(), StandardCopyOption.COPY_ATTRIBUTES, StandardCopyOption.REPLACE_EXISTING);
                        } catch (IOException e) {
                            getLog().warn("Failed to copy generated File: '" + file.getAbsolutePath() + "' to File: " + newDest.getAbsolutePath(), e);
                        }
                    } else {
                        getLog().info("Ignore File: '" + file.getAbsolutePath());
                    }
                }
            }
        }
    }

    private void installFMDescriptor(Artifact artifact) {
        if(installConvertedCP) {
            Collection<Artifact> artifacts = Collections.synchronizedCollection(new ArrayList<>());
            // Source FM Descriptor File Path
            String fmDescriptorFilePath = fmPrefix + artifact.getArtifactId() + ".json";
            File fmDescriptorFile = new File(fmOutput, fmDescriptorFilePath);
            if(fmDescriptorFile.exists() && fmDescriptorFile.canRead()) {
                // Need to create a new Artifact Handler for the different extension and an Artifact to not
                // change the module artifact
                DefaultArtifactHandler fmArtifactHandler = new DefaultArtifactHandler("slingosgifeature");
                DefaultArtifact fmArtifact = new DefaultArtifact(
                    artifact.getGroupId(), artifact.getArtifactId(), artifact.getVersion(),
                    artifact.getScope(), "slingosgifeature", artifact.getArtifactId(), fmArtifactHandler
                );
                fmArtifact.setFile(fmDescriptorFile);
                artifacts.add(fmArtifact);
                try {
                    installArtifact(mavenSession.getProjectBuildingRequest(), artifacts);
                } catch (MojoFailureException | MojoExecutionException e) {
                    getLog().error("Failed to install FM Descriptor", e);
                }
            } else {
                getLog().error("Could not find FM Descriptor File: " + fmDescriptorFile);
            }
        }
    }

    private void installArtifact(ProjectBuildingRequest pbr, Collection<Artifact> artifacts )
        throws MojoFailureException, MojoExecutionException
    {
        try
        {
            installer.install(pbr, artifacts);
        }
        catch ( ArtifactInstallerException e )
        {
            throw new MojoExecutionException( "ArtifactInstallerException", e );
        }
    }

}
