/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 ~ 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.IOException;
import java.nio.charset.StandardCharsets;
import java.nio.file.DirectoryStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Stream;

import org.apache.commons.lang3.StringUtils;
import org.apache.maven.plugin.logging.Log;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.osgi.framework.Version;
import org.osgi.framework.VersionRange;


class ResourceTypeFolderAnalyser {

    private final Log log;
    private final Path scriptsDirectory;
    private final ResourceTypeFolderPredicate resourceTypeFolderPredicate;

    ResourceTypeFolderAnalyser(@NotNull Log log, @NotNull Path scriptsDirectory) {
        this.log = log;
        this.scriptsDirectory = scriptsDirectory;
        this.resourceTypeFolderPredicate = new ResourceTypeFolderPredicate(log);
    }

    Capabilities getCapabilities(@NotNull Path resourceTypeDirectory, @NotNull Map<String, String> scriptEngineMappings) {
        Set<ProvidedCapability> providedCapabilities = new LinkedHashSet<>();
        Set<RequiredCapability> requiredCapabilities = new LinkedHashSet<>();
        String version = null;
        String resourceType = null;
        try {
            Path fileName = resourceTypeDirectory.getFileName();
            if (fileName != null) {
                version = Version.parseVersion(fileName.toString()).toString();
            }
        } catch (IllegalArgumentException ignored) {
            log.debug("No resourceType version detected in " + scriptsDirectory.resolve(resourceTypeDirectory).toString());
        }
        if (StringUtils.isNotEmpty(version)) {
            Path parent = resourceTypeDirectory.getParent();
            if (parent != null) {
                resourceType = getResourceType(parent);
            }
        } else {
            resourceType = getResourceType(resourceTypeDirectory);
        }
        if (resourceType != null) {
            String resourceTypeLabel = getResourceTypeLabel(resourceType);
            try (DirectoryStream<Path> directoryStream = Files.newDirectoryStream(scriptsDirectory.resolve(resourceTypeDirectory))) {
                for (Path directoryEntry : directoryStream) {
                    if (Files.isRegularFile(directoryEntry)) {
                        Path file = directoryEntry.getFileName();
                        if (file != null) {
                            if (MetadataMojo.EXTENDS_FILE.equals(file.toString())) {
                                processExtendsFile(resourceType, version, directoryEntry, providedCapabilities, requiredCapabilities);
                            } else if (MetadataMojo.REQUIRES_FILE.equals(file.toString())) {
                                processRequiresFile(directoryEntry, requiredCapabilities);
                            } else {
                                processScriptFile(resourceTypeDirectory, scriptEngineMappings, directoryEntry, resourceType, version,
                                        resourceTypeLabel, providedCapabilities);
                            }
                        }
                    } else if (Files.isDirectory(directoryEntry) && !resourceTypeFolderPredicate.test(directoryEntry)) {
                        try (Stream<Path> subtree = Files.walk(directoryEntry)) {
                            Iterator<Path> subtreeIterator = subtree.iterator();
                            while (subtreeIterator.hasNext()) {
                                Path subtreeEntry = subtreeIterator.next();
                                if (Files.isRegularFile(subtreeEntry)) {
                                    processScriptFile(resourceTypeDirectory, scriptEngineMappings, subtreeEntry, resourceType, version,
                                            resourceTypeLabel, providedCapabilities);
                                }
                            }
                        }
                    }
                }
            } catch (IOException | IllegalArgumentException e) {
                log.warn(String.format("Cannot analyse folder %s.", scriptsDirectory.resolve(resourceTypeDirectory).toString()), e);
            }
        }

        return new Capabilities(providedCapabilities, requiredCapabilities);
    }

    private void processExtendsFile(@NotNull String resourceType, @Nullable String version, @NotNull Path extendsFile,
                                    @NotNull Set<ProvidedCapability> providedCapabilities,
                                    @NotNull Set<RequiredCapability> requiredCapabilities)
            throws IOException {
        List<String> extendResources = Files.readAllLines(extendsFile, StandardCharsets.UTF_8);
        if (extendResources.size() == 1) {
            String extend = extendResources.get(0);
            if (StringUtils.isNotEmpty(extend)) {
                String[] extendParts = extend.split(";");
                String extendedResourceType = extendParts[0];
                String extendedResourceTypeVersion = extendParts.length > 1 ? extendParts[1] : null;
                providedCapabilities.add(
                        ProvidedCapability.builder()
                                .withResourceType(resourceType)
                                .withVersion(version)
                                .withExtendsResourceType(extendedResourceType)
                                .build());
                RequiredCapability.Builder requiredBuilder =
                        RequiredCapability.builder().withResourceType(extendedResourceType);
                try {
                    if (extendedResourceTypeVersion != null) {
                        requiredBuilder.withVersionRange(
                                VersionRange.valueOf(extendedResourceTypeVersion.substring(extendedResourceTypeVersion.indexOf('=') + 1)));
                    }
                } catch (IllegalArgumentException ignored) {
                    log.warn(String.format("Invalid version range '%s' defined for extended resourceType '%s'" +
                                    " in file %s.", extendedResourceTypeVersion, extendedResourceType,
                            extendsFile.toString()));
                }
                requiredCapabilities.add(requiredBuilder.build());
            }
        }
    }

    private void processRequiresFile(@NotNull Path requiresFile,
                                     @NotNull Set<RequiredCapability> requiredCapabilities)
            throws IOException {
        List<String> requiredResourceTypes = Files.readAllLines(requiresFile, StandardCharsets.UTF_8);
        for (String requiredResourceType : requiredResourceTypes) {
            if (StringUtils.isNotEmpty(requiredResourceType)) {
                String[] requireParts = requiredResourceType.split(";");
                String resourceType = requireParts[0];
                String version = requireParts.length > 1 ? requireParts[1] : null;
                RequiredCapability.Builder requiredBuilder =
                        RequiredCapability.builder().withResourceType(resourceType);
                try {
                    if (version != null) {
                        requiredBuilder.withVersionRange(VersionRange.valueOf(version.substring(version.indexOf('=') + 1)));
                    }
                } catch (IllegalArgumentException ignored) {
                    log.warn(String.format("Invalid version range '%s' defined for required resourceType '%s'" +
                                    " in file %s.", version, resourceType,
                            requiresFile.toString()));
                }
                requiredCapabilities.add(requiredBuilder.build());
            }
        }
    }

    private void processScriptFile(@NotNull Path resourceTypeDirectory, @NotNull Map<String, String> scriptEngineMappings,
                                   @NotNull Path script, @NotNull String resourceType, @Nullable String version,
                                   @NotNull String resourceTypeLabel, @NotNull Set<ProvidedCapability> providedCapabilities) {
        Path scriptFile = script.getFileName();
        if (scriptFile != null) {
            Path relativeResourceTypeFolder = resourceTypeDirectory.relativize(script);
            int pathSegments = relativeResourceTypeFolder.getNameCount();
            ArrayList<String> selectors = new ArrayList<>();
            if (pathSegments > 1) {
                for (int i = 0; i < pathSegments - 1; i++) {
                    selectors.add(relativeResourceTypeFolder.getName(i).toString());
                }
            }
            String[] parts = scriptFile.toString().split("\\.");
            if (parts.length >= 2 && parts.length <= 4) {
                String method = null;
                String requestExtension = null;
                String scriptExtension = parts[parts.length - 1];
                String first = parts[0];
                if (!first.equals(resourceTypeLabel)) {
                    if (MetadataMojo.METHODS.contains(first)) {
                        // method script
                        method = first;
                        if ("HEAD".equals(method) || "GET".equals(method)) {
                            if (parts.length == 4) {
                                selectors.add(parts[1]);
                                requestExtension = parts[2];
                            } else if (parts.length == 3) {
                                String middlePart = parts[1];
                                if (MimeTypeChecker.hasMimeType(middlePart)) {
                                    requestExtension = middlePart;
                                } else {
                                    selectors.add(middlePart);
                                }
                            }
                        } else {
                            if (parts.length != 2) {
                                log.warn(String.format("Script %s doesn't respect naming conventions. Only GET and HEAD scripts are " +
                                        "allowed to use additional selectors or request extensions.", script.toString()));
                                return;
                            }
                        }
                    } else {
                        // selector script
                        if (parts.length == 3) {
                            selectors.add(first);
                            requestExtension = parts[1];
                        } else if (parts.length == 2) {
                            selectors.add(first);
                        } else {
                            log.warn(String.format("Script %s doesn't respect naming conventions. A selector script can contain at max " +
                                    "the request extension, but no other selectors."));
                            return;
                        }
                    }
                } else {
                    // main script
                    if (parts.length > 3) {
                        log.warn(String.format("Script %s doesn't respect naming conventions. The main script can contain at max " +
                                "the request extension, but no other selectors."));
                        return;
                    }
                    if (parts.length == 3) {
                        requestExtension = parts[parts.length - 2];
                    }
                }
                String scriptEngine = scriptEngineMappings.get(scriptExtension);
                if (StringUtils.isNotEmpty(scriptEngine)) {
                    providedCapabilities.add(ProvidedCapability.builder().withResourceType(resourceType).withScriptEngine(scriptEngine)
                            .withVersion(version).withSelectors(selectors).withRequestExtension(requestExtension).withRequestMethod(method)
                            .build());
                } else {
                    log.warn(String.format("Unknown script engine mapping for script %s. Skipping.", scriptFile.toString()));
                }
            } else {
                log.warn(String.format("Skipping script %s since it either does not target a script engine or it provides too many " +
                        "selector parts in its name.", script.toString()));
            }
        } else {
            log.warn(String.format("Skipping path %s since it has 0 elements.", script.toString()));
        }

    }

    private String getResourceType(@NotNull Path resourceTypeFolder) {
        StringBuilder stringBuilder = new StringBuilder();
        Path relativeResourceTypePath = scriptsDirectory.relativize(resourceTypeFolder);
        if (StringUtils.isNotEmpty(relativeResourceTypePath.toString())) {
            int parts = relativeResourceTypePath.getNameCount();
            for (int i = 0; i < parts; i++) {
                stringBuilder.append(relativeResourceTypePath.getName(i));
                if (i < parts - 1) {
                    stringBuilder.append('/');
                }
            }
        }
        return stringBuilder.toString();
    }

    private @NotNull String getResourceTypeLabel(@NotNull String resourceType) {
        String resourceTypeLabel = null;
        if (resourceType.contains("/")) {
            int lastIndex = resourceType.lastIndexOf('/');
            if (lastIndex < resourceType.length() - 2) {
                resourceTypeLabel = resourceType.substring(++lastIndex);
            }
        } else if (resourceType.contains(".")) {
            int lastIndex = resourceType.lastIndexOf('.');
            if (lastIndex < resourceType.length() - 2) {
                resourceTypeLabel = resourceType.substring(++lastIndex);
            }
        } else {
            resourceTypeLabel = resourceType;
        }
        if (StringUtils.isEmpty(resourceTypeLabel)) {
            throw new IllegalArgumentException(String.format("Resource type '%s' does not provide a resourceTypeLabel.", resourceType));
        }
        return resourceTypeLabel;
    }
}
