/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 ~ 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.scriptingbundle.plugin.bnd;

import java.io.IOException;
import java.nio.file.FileSystems;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.PathMatcher;
import java.nio.file.Paths;
import java.nio.file.StandardCopyOption;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.Set;
import java.util.stream.Collectors;
import java.util.stream.Stream;

import org.apache.commons.lang3.StringUtils;
import org.apache.sling.scriptingbundle.plugin.capability.Capabilities;
import org.apache.sling.scriptingbundle.plugin.processor.Constants;
import org.apache.sling.scriptingbundle.plugin.processor.Logger;

import aQute.bnd.osgi.Analyzer;
import aQute.bnd.service.AnalyzerPlugin;
import aQute.bnd.service.Plugin;
import aQute.service.reporter.Reporter;

public class BundledScriptsScannerPlugin implements AnalyzerPlugin, Plugin {

    public static final String GLOB = "glob:";
    static final String PROJECT_BUILD_FOLDER = "project.output";
    static final String PROJECT_ROOT_FOLDER = "project.dir";

    private Map<String, String> pluginProperties;
    private Reporter reporter;
    private Logger logger;

    private Capabilities capabilities;
    private Map<String, String> scriptEngineMappings;

    @Override
    public boolean analyzeJar(Analyzer analyzer) throws Exception {
        logger = new BndLogger(reporter);
        boolean inContentPackage = "content-package".equals(analyzer.get("project.packaging"));
        Path workDirectory = Paths.get(analyzer.get(PROJECT_BUILD_FOLDER), "scriptingbundle-maven-plugin");
        Files.createDirectories(workDirectory);
        Set<PathMatcher> includes = getConfiguredIncludes();
        Set<PathMatcher> excludes = getConfiguredExcludes();
        getConfiguredSourceDirectories().stream().map(sourceDirectory -> {
            Path sourceDirectoryPath = Paths.get(sourceDirectory);
            if (!Files.exists(sourceDirectoryPath)) {
                sourceDirectoryPath = Paths.get(analyzer.get(PROJECT_ROOT_FOLDER), sourceDirectory);
            }
            return sourceDirectoryPath;
        }).filter(sourceDirectoryPath -> Files.exists(sourceDirectoryPath) && Files.isDirectory(sourceDirectoryPath)).forEach(sourceDirectoryPath -> {
            try (Stream<Path> includedFiles = walkPath(sourceDirectoryPath, includes, excludes)) {
                includedFiles.forEach(
                    file -> {
                        try {
                            if (!Files.isDirectory(file)) {
                                Path workingCopy = Paths.get(workDirectory.toString(), sourceDirectoryPath.relativize(file).toString());
                                Files.createDirectories(workingCopy.getParent());
                                Files.copy(file, workingCopy, StandardCopyOption.REPLACE_EXISTING);
                            }
                        } catch (IOException e) {
                            logger.error("Cannot copy file into working directory.", e);
                        }
                    }
                );
            } catch (IOException e) {
                logger.error("Cannot analyse source folders.", e);
            }
        });
        scriptEngineMappings = getConfiguredScriptEngineMappings();
        capabilities = Capabilities
                .fromFileSystemTree(workDirectory, walkPath(workDirectory, includes, excludes), logger,
                getConfiguredSearchPaths(), scriptEngineMappings, getMissingRequirementsOptional(), inContentPackage);
        String providedCapabilitiesDefinition = capabilities.getProvidedCapabilitiesString();
        String requiredCapabilitiesDefinition = capabilities.getRequiredCapabilitiesString();

        String providedCapabilities = analyzer.get(aQute.bnd.osgi.Constants.PROVIDE_CAPABILITY);
        if (StringUtils.isNotEmpty(providedCapabilities)) {
            providedCapabilities += ", " + providedCapabilitiesDefinition;
        } else {
            providedCapabilities = providedCapabilitiesDefinition;
        }
        analyzer.set(aQute.bnd.osgi.Constants.PROVIDE_CAPABILITY, providedCapabilities);

        String requiredCapabilities = analyzer.get(aQute.bnd.osgi.Constants.REQUIRE_CAPABILITY);
        if (StringUtils.isNotEmpty(requiredCapabilities)) {
            requiredCapabilities += ", " + requiredCapabilitiesDefinition;
        } else {
            requiredCapabilities = requiredCapabilitiesDefinition;
        }
        analyzer.set(aQute.bnd.osgi.Constants.REQUIRE_CAPABILITY, requiredCapabilities);
        return false;
    }

    @Override
    public void setProperties(Map<String, String> pluginProperties) {
        this.pluginProperties = pluginProperties;
    }

    @Override
    public void setReporter(Reporter reporter) {
        this.reporter = reporter;
    }

    public Capabilities getCapabilities() {
        return capabilities;
    }

    public Map<String, String> getScriptEngineMappings() {
        return scriptEngineMappings;
    }

    private Set<String> getConfiguredSourceDirectories() {
        String sourceDirectoriesCSV = pluginProperties.get(Constants.BND_SOURCE_DIRECTORIES);
        if (StringUtils.isNotEmpty(sourceDirectoriesCSV)) {
            return Collections.unmodifiableSet(Arrays.stream(sourceDirectoriesCSV.split(",")).map(String::trim).collect(Collectors.toSet()));
        }
        return Constants.DEFAULT_SOURCE_DIRECTORIES;
    }

    private Set<PathMatcher> getConfiguredExcludes() {
        String excludesCSV = pluginProperties.get(Constants.BND_EXCLUDES);
        if (StringUtils.isNotEmpty(excludesCSV)) {
            return Collections.unmodifiableSet(Arrays.stream(excludesCSV.split(",")).map(String::trim)
                    .map(pattern -> FileSystems.getDefault().getPathMatcher(GLOB + pattern)).collect(
                            Collectors.toSet()));
        }
        return Collections.unmodifiableSet(Constants.DEFAULT_EXCLUDES.stream().map(pattern -> FileSystems.getDefault().getPathMatcher(GLOB + pattern))
                .collect(Collectors.toSet()));
    }

    private Set<PathMatcher> getConfiguredIncludes() {
        String includesCSV = pluginProperties.get(Constants.BND_INCLUDES);
        if (StringUtils.isNotEmpty(includesCSV)) {
            return Collections.unmodifiableSet(Arrays.stream(includesCSV.split(",")).map(String::trim)
                    .map(pattern -> FileSystems.getDefault().getPathMatcher(GLOB + pattern)).collect(
                            Collectors.toSet()));
        }
        return Collections.emptySet();
    }

    private Map<String, String> getConfiguredScriptEngineMappings() {
        HashMap<String, String> mappings = new HashMap<>(Constants.DEFAULT_EXTENSION_TO_SCRIPT_ENGINE_MAPPING);
        String scriptEngineMappingsCSV = pluginProperties.get(Constants.BND_SCRIPT_ENGINE_MAPPINGS);
        if (StringUtils.isNotEmpty(scriptEngineMappingsCSV)) {
            List<String> extensionEngineMappings =
                    Arrays.stream(scriptEngineMappingsCSV.split(",")).map(String::trim).collect(Collectors.toList());
            extensionEngineMappings.forEach(mapping -> {
                String[] mappingArray = mapping.split(":");
                if (mappingArray.length != 2) {
                    logger.error(String.format("Invalid script engine mapping: %s.", mapping));
                } else {
                    mappings.put(mappingArray[0].trim(), mappingArray[1].trim());
                }
            });
        }
        return Collections.unmodifiableMap(mappings);
    }

    private Set<String> getConfiguredSearchPaths() {
        String searchPathsString = pluginProperties.get(Constants.BND_SEARCH_PATHS);
        if (StringUtils.isNotEmpty(searchPathsString)) {
            return Collections.unmodifiableSet(Arrays.stream(searchPathsString.split(",")).map(String::trim).collect(Collectors.toSet()));
        }
        return Constants.DEFAULT_SEARCH_PATHS;
    }

    private boolean getMissingRequirementsOptional() {
        String missingRequirementsOptionalString = pluginProperties.get(Constants.BND_MISSING_REQUIREMENTS_OPTIONAL);
        if (missingRequirementsOptionalString != null) {
            missingRequirementsOptionalString = missingRequirementsOptionalString.trim().toLowerCase();
            return !"false".equals(missingRequirementsOptionalString);
        }
        return true;
    }

    private Stream<Path> walkPath(Path path, Set<PathMatcher> includes, Set<PathMatcher> excludes) throws IOException {
        return Files.walk(path).filter(file -> {
            boolean include = includes.isEmpty();
            Optional<PathMatcher> includeOptions = includes.stream().filter(pathMatcher -> pathMatcher.matches(file)).findFirst();
            if (includeOptions.isPresent()) {
                include = true;
            }
            Optional<PathMatcher> excludeOptions = excludes.stream().filter(pathMatcher -> pathMatcher.matches(file)).findFirst();
            if (excludeOptions.isPresent()) {
                include = false;
            }
            return include;
        }).flatMap(file -> {
            if (!Files.isDirectory(file)) {
                return Stream.of(file, file.getParent());
            }
            return Stream.of(file);
        });
    }

}
