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

import java.io.File;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.Set;
import java.util.stream.Collectors;

import javax.script.ScriptEngineFactory;

import org.apache.maven.plugin.AbstractMojo;
import org.apache.maven.plugin.MojoExecutionException;
import org.apache.maven.plugins.annotations.LifecyclePhase;
import org.apache.maven.plugins.annotations.Mojo;
import org.apache.maven.plugins.annotations.Parameter;
import org.apache.maven.project.MavenProject;
import org.apache.maven.shared.utils.io.DirectoryScanner;
import org.jetbrains.annotations.NotNull;
import org.osgi.framework.Constants;
import org.osgi.framework.VersionRange;

/**
 * The {@code metadata} goal will generate two Maven project properties, namely
 * {@code org.apache.sling.scriptingbundle.maven.plugin.Require-Capability} and
 * {@code org.apache.sling.scriptingbundle.maven.plugin.Provide-Capability} which can be used to generate the
 * corresponding OSGi bundle headers for bundles providing scripts executable by a {@link javax.script.ScriptEngine}.
 */
@Mojo(name = "metadata",
      defaultPhase = LifecyclePhase.PACKAGE)
public class MetadataMojo extends AbstractMojo {

    @Parameter(defaultValue = "${project}",
               readonly = true)
    private MavenProject project;

    /**
     * Defines where this goal will look for scripts in the project.
     *
     * @since 0.1.0
     */
    @Parameter(defaultValue = "${project.basedir}/src/main/resources/javax.script")
    private String scriptsDirectory;

    /**
     * Allows overriding the default extension to script engine mapping, in order to correctly generate the
     * {@code sling.resourceType;scriptEngine} {@code Provide-Capability} attribute value. When configuring this mapping, please make
     * sure to use the script extension as the key and one of the Script Engine's name (obtained from
     * {@link ScriptEngineFactory#getNames()}) as the value.
     *
     * <p>The following list represents the default extension to Script Engine mapping:</p>
     * <dl>
     *     <dt>ftl</dt>
     *     <dd>freemarker</dd>
     *
     *     <dt>gst</dt>
     *     <dd>gstring</dd>
     *
     *     <dt>html</dt>
     *     <dd>htl</dd>
     *
     *     <dt>java</dt>
     *     <dd>java</dd>
     *
     *     <dt>esp, ecma</dt>
     *     <dd>rhino</dd>
     *
     *     <dt>jsp, jspf, jspx</dt>
     *     <dd>jsp</dd>
     * </dl>
     *
     * @since 0.2.0
     */
    @Parameter
    private Map<String, String> scriptEngineMappings;

    static final Set<String> METHODS = new HashSet<>(Arrays.asList("TRACE", "OPTIONS", "GET", "HEAD", "POST", "PUT",
            "DELETE", "PATCH"));
    static final String EXTENDS_FILE = "extends";
    static final String REQUIRES_FILE = "requires";
    static final String CAPABILITY_NS = "sling.resourceType";
    static final String CAPABILITY_SELECTORS_AT = CAPABILITY_NS + ".selectors:List<String>";
    static final String CAPABILITY_EXTENSIONS_AT = CAPABILITY_NS + ".extensions:List<String>";
    static final String CAPABILITY_METHODS_AT = "sling.servlet.methods:List<String>";
    static final String CAPABILITY_VERSION_AT = "version:Version";
    static final String CAPABILITY_EXTENDS_AT = "extends";
    static final String CAPABILITY_SCRIPT_ENGINE_AT = "scriptEngine";
    static final Map<String, String> DEFAULT_EXTENSION_TO_SCRIPT_ENGINE_MAPPING;

    static {
        DEFAULT_EXTENSION_TO_SCRIPT_ENGINE_MAPPING = new HashMap<>();
        DEFAULT_EXTENSION_TO_SCRIPT_ENGINE_MAPPING.put("ftl", "freemarker");
        DEFAULT_EXTENSION_TO_SCRIPT_ENGINE_MAPPING.put("gst", "gstring");
        DEFAULT_EXTENSION_TO_SCRIPT_ENGINE_MAPPING.put("html", "htl");
        DEFAULT_EXTENSION_TO_SCRIPT_ENGINE_MAPPING.put("java", "java");
        DEFAULT_EXTENSION_TO_SCRIPT_ENGINE_MAPPING.put("esp", "rhino");
        DEFAULT_EXTENSION_TO_SCRIPT_ENGINE_MAPPING.put("ecma", "rhino");
        DEFAULT_EXTENSION_TO_SCRIPT_ENGINE_MAPPING.put("jsp", "jsp");
        DEFAULT_EXTENSION_TO_SCRIPT_ENGINE_MAPPING.put("jspf", "jsp");
        DEFAULT_EXTENSION_TO_SCRIPT_ENGINE_MAPPING.put("jspx", "jsp");
        /*
         * commented out since Thymeleaf uses the same 'html' extension like HTL
         */
//        DEFAULT_EXTENSION_TO_SCRIPT_ENGINE_MAPPING.put("html", "thymeleaf");
    }

    private Capabilities capabilities;

    public void execute() throws MojoExecutionException {
        File sdFile = new File(scriptsDirectory);
        if (!sdFile.exists()) {
            sdFile = new File(project.getBasedir(), scriptsDirectory);
            if (!sdFile.exists()) {
                throw new MojoExecutionException("Cannot find file " + scriptsDirectory + ".");
            }
        }
        final String root = sdFile.getAbsolutePath();
        DirectoryScanner scanner = new DirectoryScanner();
        scanner.setBasedir(sdFile);
        scanner.setIncludes("**");
        scanner.setExcludes("**/*.class");
        scanner.addDefaultExcludes();
        scanner.scan();
        List<String> includedDirectories = Arrays.asList(scanner.getIncludedDirectories());
        includedDirectories.sort(Collections.reverseOrder());
        List<Path> resourceTypeDirectories =
                includedDirectories.stream()
                        .map(includedDirectory -> Paths.get(root, includedDirectory))
                        .filter(new ResourceTypeFolderPredicate(getLog())).collect(Collectors.toList());

        getLog().info("Detected resource type directories: " + resourceTypeDirectories);
        Map<String, String> mappings = new HashMap<>(DEFAULT_EXTENSION_TO_SCRIPT_ENGINE_MAPPING);
        if (scriptEngineMappings != null) {
            mappings.putAll(scriptEngineMappings);
        }
        capabilities = generateCapabilities(root, resourceTypeDirectories, mappings);
        String providedCapabilitiesDefinition = getProvidedCapabilitiesString(capabilities);
        String requiredCapabilitiesDefinition = getRequiredCapabilitiesString(capabilities);
        project.getProperties().put(this.getClass().getPackage().getName() + "." + Constants.PROVIDE_CAPABILITY,
                    providedCapabilitiesDefinition);
        project.getProperties().put(this.getClass().getPackage().getName() + "." + Constants.REQUIRE_CAPABILITY,
                    requiredCapabilitiesDefinition);
    }

    @NotNull
    private Capabilities generateCapabilities(@NotNull String root, @NotNull List<Path> resourceTypeDirectories, @NotNull Map<String,
            String> scriptEngineMappings) {
        ResourceTypeFolderAnalyser analyser = new ResourceTypeFolderAnalyser(getLog(), Paths.get(root));
        Set<ProvidedCapability> providedCapabilities = new LinkedHashSet<>();
        Set<RequiredCapability> requiredCapabilities = new LinkedHashSet<>();
        for (Path resourceTypeDirectory : resourceTypeDirectories) {
            Capabilities resourceTypeCapabilities = analyser.getCapabilities(resourceTypeDirectory, scriptEngineMappings);
            providedCapabilities.addAll(resourceTypeCapabilities.getProvidedCapabilities());
            requiredCapabilities.addAll(resourceTypeCapabilities.getRequiredCapabilities());
        }
        return new Capabilities(providedCapabilities, requiredCapabilities);
    }

    @NotNull
    private String getProvidedCapabilitiesString(Capabilities capabilities) {
        StringBuilder builder = new StringBuilder();
        int pcNum = capabilities.getProvidedCapabilities().size();
        int pcIndex = 0;
        for (ProvidedCapability capability : capabilities.getProvidedCapabilities()) {
            builder.append(CAPABILITY_NS).append(";");
            builder.append(CAPABILITY_NS).append("=").append("\"").append(capability.getResourceType()).append("\"");
            Optional.ofNullable(capability.getScriptEngine()).ifPresent(scriptEngine ->
                    builder.append(";")
                            .append(CAPABILITY_SCRIPT_ENGINE_AT).append("=").append("\"").append(scriptEngine).append("\"")
            );
            Optional.ofNullable(capability.getVersion()).ifPresent(version ->
                    builder.append(";")
                            .append(CAPABILITY_VERSION_AT).append("=").append("\"").append(version).append("\"")
            );
            Optional.ofNullable(capability.getExtendsResourceType()).ifPresent(extendedResourceType ->
                    builder.append(";")
                            .append(CAPABILITY_EXTENDS_AT).append("=").append("\"").append(extendedResourceType).append("\"")
            );
            Optional.ofNullable(capability.getRequestMethod()).ifPresent(method ->
                    builder.append(";")
                            .append(CAPABILITY_METHODS_AT).append("=").append("\"").append(method).append("\"")
            );
            Optional.ofNullable(capability.getRequestExtension()).ifPresent(requestExtension ->
                    builder.append(";")
                            .append(CAPABILITY_EXTENSIONS_AT).append("=").append("\"").append(requestExtension).append("\"")
            );
            if (!capability.getSelectors().isEmpty()) {
                builder.append(";").append(CAPABILITY_SELECTORS_AT).append("=").append("\"");
                List<String> selectors = capability.getSelectors();
                int selectorsSize = selectors.size();
                int selectorIndex = 0;
                for (String selector : selectors) {
                    builder.append(selector);
                    if (selectorIndex < selectorsSize - 1) {
                        builder.append(",");
                    }
                    selectorIndex++;
                }
                builder.append("\"");
            }
            if (pcIndex < pcNum - 1) {
                builder.append(",");
            }
            pcIndex++;
        }
        return builder.toString();
    }

    @NotNull
    private String getRequiredCapabilitiesString(Capabilities capabilities) {
        StringBuilder builder = new StringBuilder();
        int pcNum = capabilities.getRequiredCapabilities().size();
        int pcIndex = 0;
        for (RequiredCapability capability : capabilities.getRequiredCapabilities()) {
            builder.append(CAPABILITY_NS).append(";filter:=\"").append("(&(!(sling.resourceType.selectors=*))");
            VersionRange versionRange = capability.getVersionRange();
            if (versionRange != null) {
                builder.append("(&").append(versionRange.toFilterString("version")).append("(").append(CAPABILITY_NS).append("=").append(capability.getResourceType()).append("))");
            } else {
                builder.append("(").append(CAPABILITY_NS).append("=").append(capability.getResourceType()).append(")");
            }
            builder.append(")\"");
            if (pcIndex < pcNum - 1) {
                builder.append(",");
            }
            pcIndex++;
        }
        return builder.toString();
    }

    Capabilities getCapabilities() {
        return capabilities;
    }

}
