/*
 * 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.scanner.impl;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.nio.file.Files;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Enumeration;
import java.util.HashSet;
import java.util.List;
import java.util.Properties;
import java.util.Set;
import java.util.jar.JarFile;
import java.util.jar.Manifest;
import java.util.zip.ZipEntry;

import org.apache.sling.feature.Artifact;
import org.apache.sling.feature.ArtifactId;
import org.apache.sling.feature.Configuration;
import org.apache.sling.feature.io.IOUtils;
import org.apache.sling.feature.scanner.BundleDescriptor;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * Scan the contents of a content package.
 */
public class ContentPackageScanner {

    private static final String FILE_PACKAGE_PROPS = "META-INF/vault/properties.xml";

    private static final String FILE_MANIFEST = "META-INF/MANIFEST.MF";

    private final Logger logger = LoggerFactory.getLogger(this.getClass());

    private final byte[] buffer = new byte[65536];

    enum FileType {
        BUNDLE,
        CONFIG,
        PACKAGE,
    }

    private static final List<String> CFG_EXTENSIONS = Arrays.asList(".config", ".cfg", ".cfg.json", ".xml");

    /**
     * Scan the content package for embedded artifacts
     * @param artifact The content package
     * @param url The url to the binary
     * @return A set of artifacts
     * @throws IOException If processing fails
     */
    public Set<ContentPackageDescriptorImpl> scan(final Artifact artifact, final URL url) throws IOException {
        final Set<ContentPackageDescriptorImpl> contentPackages = new HashSet<>();
        if (url != null) {
            final String path = url.getPath();
            final int lastDotInUrl = path.lastIndexOf(".");
            final String name = path.substring(path.lastIndexOf("/") + 1, lastDotInUrl);
             extractContentPackage(null, null, artifact, name, url, contentPackages);
        }

        return contentPackages;
    }

    /**
     * Detect the file type, bundle, configuration or embedded package from the content path
     * @param contentPath The content path
     * @return The detected file type or {@code null}
     */
    FileType detectContentFileType(final String contentPath) {
        FileType fileType = null;

        // check for install folders in libs or apps
        if (contentPath.startsWith("/libs/") || contentPath.startsWith("/apps/")) {

            // check if this is an install folder (I)
            // install folders are either named:
            // "install" or
            // "install.{runmode}"
            boolean isInstall = contentPath.indexOf("/install/") != -1;
            if (!isInstall) {
                final int pos = contentPath.indexOf("/install.");
                if (pos != -1) {
                    final int endSlashPos = contentPath.indexOf('/', pos + 1);
                    if (endSlashPos != -1) {
                        isInstall = true;
                    }
                }
            }
            if (!isInstall) {
                // check if this is an install folder (II)
                // config folders are either named:
                // "config" or
                // "config.{runmode}"
                isInstall = contentPath.indexOf("/config/") != -1;
                if (!isInstall) {
                    final int pos = contentPath.indexOf("/config.");
                    if (pos != -1) {
                        final int endSlashPos = contentPath.indexOf('/', pos + 1);
                        if (endSlashPos != -1) {
                            isInstall = true;
                        }
                    }
                }
            }

            if (isInstall) {

                if (contentPath.endsWith(".jar")) {
                    fileType = FileType.BUNDLE;

                } else if (contentPath.endsWith(".zip")) {
                    fileType = FileType.PACKAGE;

                } else {
                    for(final String ext : CFG_EXTENSIONS) {
                        if ( contentPath.endsWith(ext) ) {
                            fileType = FileType.CONFIG;
                            break;
                        }
                    }
                }
            }
        } else if ( contentPath.startsWith("/etc/packages/") && contentPath.endsWith(".zip")) {
            // embedded content package
            fileType = FileType.PACKAGE;
        }
        return fileType;
    }

    private ContentPackageDescriptorImpl extractContentPackage(final ContentPackageDescriptorImpl parentPackage,
            final String parentContentPath,
            final Artifact packageArtifact,
            final String name,
            final URL archiveUrl,
            final Set<ContentPackageDescriptorImpl> infos)
    throws IOException {
        logger.debug("Analyzing Content Package {}", archiveUrl);

        final File tempDir = Files.createTempDirectory(null).toFile();
        try {
            final File toDir = new File(tempDir, archiveUrl.getPath().substring(archiveUrl.getPath().lastIndexOf("/") + 1));
            toDir.mkdirs();

            Manifest manifest = null;
            final List<File> toProcess = new ArrayList<>();
            final List<String> contentPaths = new ArrayList<>();
            final List<BundleDescriptor> bundles = new ArrayList<>();
            final List<Configuration> configs = new ArrayList<>();
            final Properties packageProps = new Properties();

            try (final JarFile zipFile = IOUtils.getJarFileFromURL(archiveUrl, true, null)) {
                Enumeration<? extends ZipEntry> entries = zipFile.entries();
                while (entries.hasMoreElements()) {
                    final ZipEntry entry = entries.nextElement();
                    final String entryName = entry.getName();

                    // skip dirs
                    if ( entryName.endsWith("/") ) {
                        continue;
                    }

                    logger.debug("Content package entry {}", entryName);

                    if ( entryName.startsWith("jcr_root/") ) {
                        final String contentPath = entryName.substring(8);
                        contentPaths.add(contentPath);

                        final FileType fileType = detectContentFileType(contentPath);
                        if (fileType != null) {
                            logger.debug("- extracting : {}", contentPath);
                            final File newFile = new File(toDir, entryName.replace('/', File.separatorChar));
                            newFile.getParentFile().mkdirs();

                            try (
                                    final FileOutputStream fos = new FileOutputStream(newFile);
                                    final InputStream zis = zipFile.getInputStream(entry);
                            ) {
                                int len;
                                while ((len = zis.read(buffer)) > -1) {
                                    fos.write(buffer, 0, len);
                                }
                            }

                            if (fileType == FileType.BUNDLE) {
                                int startLevel = 20;
                                final int lastSlash = contentPath.lastIndexOf('/');
                                final int nextSlash = contentPath.lastIndexOf('/', lastSlash - 1);
                                final String part = contentPath.substring(nextSlash + 1, lastSlash);
                                try {
                                    startLevel = Integer.valueOf(part);
                                } catch (final NumberFormatException ignore) {
                                    // ignore
                                }

                                final Artifact bundle = new Artifact(extractArtifactId(packageArtifact.getId(), newFile));
                                bundle.setStartOrder(startLevel);
                                final BundleDescriptor info = new BundleDescriptorImpl(bundle, newFile.toURI().toURL(),
                                        startLevel);
                                bundle.getMetadata().put(ContentPackageDescriptorImpl.METADATA_PACKAGE,
                                        packageArtifact.getId().toMvnId());
                                bundle.getMetadata().put(ContentPackageDescriptorImpl.METADATA_PATH, contentPath);

                                bundles.add(info);

                            } else if (fileType == FileType.CONFIG) {

                                final Configuration configEntry = this.processConfiguration(newFile, packageArtifact.getId(), contentPath);
                                if (configEntry != null) {
                                    configs.add(configEntry);
                                }

                            } else if (fileType == FileType.PACKAGE) {
                                toProcess.add(newFile);
                            }
                        }
                    } else if ( FILE_MANIFEST.equals(entry.getName()) ) {
                        try ( final InputStream zis = zipFile.getInputStream(entry)) {
                            manifest = new Manifest(zis);
                        } catch ( final IOException ignore ) {
                            logger.warn("Failure reading manifest from {} : {}", packageArtifact.getId(), ignore.getMessage());
                        }
                    } else if ( FILE_PACKAGE_PROPS.equals(entry.getName()) ) {
                        try ( final InputStream zis = zipFile.getInputStream(entry)) {
                            packageProps.loadFromXML(zis);
                        }
                    }
                }

                final ContentPackageDescriptorImpl desc = new ContentPackageDescriptorImpl(name, packageArtifact, archiveUrl, manifest,
                    bundles, contentPaths, configs, packageProps);
                if ( parentPackage != null ) {
                    desc.setParentContentPackageInfo(parentPackage, parentContentPath);
                }

                for (final File f : toProcess) {
                    final int lastDot = f.getName().lastIndexOf(".");
                    final String subName = f.getName().substring(0, lastDot);
                    final String contentPath = f.getAbsolutePath().substring(toDir.getAbsolutePath().length()).replace(File.separatorChar, '/');

                    // create synthetic artifact with a synthetic id containing the file name
                    final Artifact subArtifact = new Artifact(packageArtifact.getId().changeClassifier(subName));

                    extractContentPackage(desc, contentPath, subArtifact, subName, f.toURI().toURL(), infos);
                }

                infos.add(desc);
                desc.lock();
                return desc;
            }
        } finally {
            deleteOnExitRecursive(tempDir);
        }
    }

    private void deleteOnExitRecursive(File file) {
        file.deleteOnExit();
        if (file.isDirectory()) {
            File[] childs = file.listFiles();
            if (childs != null) {
                for (File child : childs) {
                    deleteOnExitRecursive(child);
                }
            }
        }
    }

    final List<Properties> getInitialCandidates(final File bundleFile)  throws IOException{
        logger.debug("Extracting Bundle {}", bundleFile.getName());

        final List<Properties> candidates = new ArrayList<>();
        try (final JarFile zipFile = new JarFile(bundleFile)) {
            Enumeration<? extends ZipEntry> entries = zipFile.entries();

            while ( entries.hasMoreElements() ) {
                final ZipEntry entry = entries.nextElement();

                final String entryName = entry.getName();
                if ( !entryName.endsWith("/") && entryName.startsWith("META-INF/maven/") && entryName.endsWith("/pom.properties")) {
                    logger.debug("- extracting : {}", entryName);

                    final Properties props = new Properties();
                    try (final InputStream zis = zipFile.getInputStream(entry)) {
                        props.load(zis);
                    }
                    candidates.add(props);
                }
            }
        }
        return candidates;
    }

    private String adjustVersion(final String version) {
        final String parts[] = version.split("\\.");
        if ( parts.length == 4 ) {
            final int lastDot = version.lastIndexOf('.');
            return version.substring(0, lastDot) + '-' + version.substring(lastDot + 1);
        }
        return version;
    }

    private ArtifactId adjustClassifier(ArtifactId id, final String bundleFileName) {
        // check for classifier
        final int versionStart = bundleFileName.indexOf(id.getVersion());
        if ( versionStart != -1 ) {
            // capture classifier
            final int versionEnd = versionStart + id.getVersion().length();
            if ( bundleFileName.length() > versionEnd && bundleFileName.charAt(versionEnd) == '-') {
                id = id.changeClassifier(bundleFileName.substring(versionEnd + 1, bundleFileName.lastIndexOf('.')));
            }
        }
        return id;
    }

    private ArtifactId extractArtifactId(final ArtifactId packageArtifactId, final File bundleFile)
    throws IOException {
        final List<Properties> candidates = this.getInitialCandidates(bundleFile);
        return extractArtifactId(candidates, bundleFile.getName(), packageArtifactId);
    }

    private List<ArtifactId> getArtifactIds(final List<Properties> candidates) {
        final List<ArtifactId> idCandidates = new ArrayList<>();
        for(final Properties props : candidates) {
            final String version = props.getProperty("version");
            final String groupId = props.getProperty("groupId");
            final String artifactId = props.getProperty("artifactId");

            if ( version != null && groupId != null && artifactId != null ) {
                idCandidates.add(new ArtifactId(groupId, artifactId, adjustVersion(version), null, null));
            }
        }
        return idCandidates;
    }

    private List<ArtifactId> filterCandidatesByVersion(final List<ArtifactId> ids, final String bundleFileName) {
        final List<ArtifactId> idCandidates = new ArrayList<>();
        for(final ArtifactId id : ids) {
            final int versionStart = bundleFileName.indexOf(id.getVersion());
            if ( versionStart != -1 ) {
                idCandidates.add(id);
            }
        }
        return idCandidates;
    }

    ArtifactId extractArtifactId(final List<Properties> candidates, final String bundleFileName, final ArtifactId packageArtifactId)
    throws IOException {
        logger.debug("Properties candidates for {} : {}", bundleFileName, candidates);

        final List<ArtifactId> idCandidates = getArtifactIds(candidates);
        logger.debug("Artifact candidates for {} : {}", bundleFileName, candidates);

        // single candidate? return
        if ( idCandidates.size() == 1 ) {
            final ArtifactId result = adjustClassifier(idCandidates.get(0), bundleFileName);
            logger.debug("Found single candidate : {}", result);
            return result;
        }

        // more than one candidate, find matching version
        final List<ArtifactId> versionIds = filterCandidatesByVersion(idCandidates, bundleFileName);
        if ( versionIds.size() == 1 ) {
            final ArtifactId result = adjustClassifier(versionIds.get(0), bundleFileName);
            logger.debug("Found single candidate matching version : {}", result);
            return result;
        }
        // check parent group id
        for(final ArtifactId id : versionIds.isEmpty() ? idCandidates : versionIds) {
            if ( id.getGroupId().equals(packageArtifactId.getGroupId()) ) {
                final ArtifactId result = adjustClassifier(id, bundleFileName);
                logger.debug("Found candidate with parent group id {} : {}",packageArtifactId.getGroupId(), result);
                return result;
            }
        }
        // randomly pick one
        if ( idCandidates.size() > 0 ) {
            final ArtifactId result = adjustClassifier(idCandidates.get(0), bundleFileName);
            logger.debug("Picking random candidate : {}", result);
            return result;
        }

        throw new IOException(bundleFileName + " has no maven coordinates!");
    }

    Configuration processConfiguration(final File configFile,
            final ArtifactId packageArtifactId,
            final String contentPath)
    throws IOException {

        boolean isConfig = true;
        if ( contentPath.endsWith(".xml") ) {
            final String contents = Files.readAllLines(configFile.toPath()).toString();
            if ( contents.indexOf("jcr:primaryType=\"sling:OsgiConfig\"") == -1 ) {
                isConfig = false;
            }
        }

        if ( isConfig ) {
            final String id;
            if ( contentPath.endsWith("/.content.xml") ) {
                final int lastSlash = contentPath.lastIndexOf('/');
                final int previousSlash = contentPath.lastIndexOf('/', lastSlash - 1);
                id = contentPath.substring(previousSlash + 1, lastSlash);
            } else {
                String name = contentPath;
                final int lastSlash = contentPath.lastIndexOf('/');
                for(final String ext : CFG_EXTENSIONS) {
                    if ( name.endsWith(ext) ) {
                        name = name.substring(lastSlash + 1, name.length() - ext.length());
                    }
                }
                id = name;
            }

            final String pid;
            final int slashPos = id.indexOf('-');
            if ( slashPos == -1 ) {
                pid = id;
            } else {
                pid = id.substring(0, slashPos) + '~' + id.substring(slashPos + 1);
            }

            final Configuration cfg = new Configuration(pid);
            cfg.getProperties().put(Configuration.PROP_PREFIX + ContentPackageDescriptorImpl.METADATA_PATH, contentPath);
            cfg.getProperties().put(Configuration.PROP_PREFIX + ContentPackageDescriptorImpl.METADATA_PACKAGE,
                    packageArtifactId.toMvnId());

            return cfg;
        }

        return null;
    }
}
