/*
 * Copyright 2016-present Open Networking Foundation
 *
 * Licensed 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.onosproject.onosjar;

import aQute.bnd.header.Attrs;
import aQute.bnd.header.Parameters;
import aQute.bnd.osgi.Analyzer;
import aQute.bnd.osgi.Builder;
import aQute.bnd.osgi.Constants;
import aQute.bnd.osgi.Descriptors;
import aQute.bnd.osgi.FileResource;
import aQute.bnd.osgi.Jar;
import aQute.bnd.osgi.Packages;
import aQute.bnd.osgi.Processor;
import aQute.bnd.osgi.Resource;
import com.facebook.buck.step.ExecutionContext;
import com.facebook.buck.step.Step;
import com.facebook.buck.step.StepExecutionResult;
import com.google.common.base.MoreObjects;
import com.google.common.collect.ImmutableSortedSet;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.google.common.collect.Sets;
import org.apache.felix.scrplugin.bnd.SCRDescriptorBndPlugin;
import org.codehaus.plexus.util.DirectoryScanner;

import java.io.File;
import java.io.IOException;
import java.io.PrintStream;
import java.nio.file.FileVisitResult;
import java.nio.file.FileVisitor;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.SimpleFileVisitor;
import java.nio.file.attribute.BasicFileAttributes;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.Set;
import java.util.jar.Manifest;
import java.util.stream.Collectors;

import static java.nio.file.Files.walkFileTree;

/**
 * BND-based wrapper to convert Buck JARs to OSGi-compatible JARs.
 */
public class OSGiWrapper implements Step {

    private Path inputJar;
    private Path outputJar;
    private Path sourcesDir;
    private Path classesDir;
    private List<String> classpath;

    private String bundleName;
    private String groupId;
    private String bundleSymbolicName;
    private String bundleVersion;

    private String importPackages;
    private String privatePackages;
    private String dynamicimportPackages;

    private String exportPackages;
    private String includeResources;
    private Set<String> includedResources = Sets.newHashSet();

    private String bundleDescription;
    private String bundleLicense;

    private String webContext;

    private PrintStream stderr = System.err;

    public OSGiWrapper(Path inputJar,
                       Path outputJar,
                       Path sourcesDir,
                       Path classesDir,
                       ImmutableSortedSet<Path> classpath,
                       String bundleName,
                       String groupId,
                       String bundleVersion,
                       String bundleLicense,
                       String importPackages,
                       String exportPackages,
                       String includeResources,
                       String webContext,
                       String dynamicimportPackages,
                       String bundleDescription,
                       String privatePackages) {
        this.inputJar = inputJar;
        this.sourcesDir = sourcesDir;
        this.classesDir = classesDir;
        this.classpath = Lists.newArrayList(
                classpath.stream().map(Path::toString).collect(Collectors.toList()));
        if (!this.classpath.contains(inputJar.toString())) {
            this.classpath.add(0, inputJar.toString());
        }
        this.outputJar = outputJar;

        this.bundleName = bundleName;
        this.groupId = groupId;
        this.bundleSymbolicName = String.format("%s.%s", groupId, bundleName);

        this.bundleVersion = bundleVersion;
        this.bundleLicense = bundleLicense;
        this.bundleDescription = bundleDescription;

        this.importPackages = importPackages;
        this.privatePackages = privatePackages;
        this.dynamicimportPackages = dynamicimportPackages;
        this.exportPackages = exportPackages;
        this.includeResources = includeResources;

        this.webContext = webContext;
    }

    private void setProperties(Analyzer analyzer) {
        analyzer.setProperty(Analyzer.BUNDLE_NAME, bundleName);
        analyzer.setProperty(Analyzer.BUNDLE_SYMBOLICNAME, bundleSymbolicName);
        analyzer.setProperty(Analyzer.BUNDLE_VERSION, bundleVersion.replace('-', '.'));

        if (bundleDescription != null) {
            analyzer.setProperty(Analyzer.BUNDLE_DESCRIPTION, bundleDescription);
        }
        if (bundleLicense != null) {
            analyzer.setProperty(Analyzer.BUNDLE_LICENSE, bundleLicense);
        }

        //TODO consider using stricter version policy
        //analyzer.setProperty("-provider-policy", "${range;[===,==+)}");
        //analyzer.setProperty("-consumer-policy", "${range;[===,==+)}");

        // There are no good defaults so make sure you set the Import-Package
        analyzer.setProperty(Analyzer.IMPORT_PACKAGE, importPackages);
        if (privatePackages != null) {
            analyzer.setProperty(Analyzer.PRIVATE_PACKAGE, privatePackages);
        }
        analyzer.setProperty(Analyzer.REMOVEHEADERS, "Private-Package,Include-Resource");

        analyzer.setProperty(Analyzer.DYNAMICIMPORT_PACKAGE,
                             dynamicimportPackages);

        // TODO include version in export, but not in import
        analyzer.setProperty(Analyzer.EXPORT_PACKAGE, exportPackages);

        // TODO we may need INCLUDE_RESOURCE, or that might be done by Buck
        // FIXME NOTE we handle this manually below
        if (includeResources != null) {
            analyzer.setProperty(Analyzer.INCLUDE_RESOURCE, includeResources);
        }

        if (isWab()) {
            analyzer.setProperty(Analyzer.WAB, "src/main/webapp/");
            analyzer.setProperty("Web-ContextPath", webContext);
            analyzer.setProperty(Analyzer.IMPORT_PACKAGE, "*,org.glassfish.jersey.servlet,org.jvnet.mimepull\n");
        }
    }

    public boolean execute() {
        Builder analyzer = new Builder();
        try {

            Jar jar = new Jar(inputJar.toFile());   // where our data is
            analyzer.setJar(jar);                   // give bnd the contents

            // You can provide additional class path entries to allow
            // bnd to pickup export version from the packageinfo file,
            // Version annotation, or their manifests.
            analyzer.addClasspath(classpath);

            setProperties(analyzer);

            // Analyze the target JAR first
            analyzer.analyze();

            // Scan the JAR for Felix SCR annotations and generate XML files
            Map<String, String> properties = Maps.newHashMap();
            properties.put("destdir", classesDir.toAbsolutePath().toString());
            SCRDescriptorBndPlugin scrDescriptorBndPlugin = new SCRDescriptorBndPlugin();
            scrDescriptorBndPlugin.setProperties(properties);
            scrDescriptorBndPlugin.setReporter(analyzer);
            scrDescriptorBndPlugin.analyzeJar(analyzer);

            //Add local packges to jar file.
            //FIXME removing this call for now; not sure what exactly it's doing
            //addLocalPackages(new File(classesDir.toString()), analyzer);

            //add resources.
            if (includeResources != null) {
                doIncludeResources(analyzer);
            }

            // Repack the JAR as a WAR
            doWabStaging(analyzer);

            // Calculate the manifest
            Manifest manifest = analyzer.calcManifest();

            //Build the jar files
            //FIXME this call conflicts with some of the above
//            analyzer.build();

            if (analyzer.isOk()) {
                //add calculated manifest file.
                analyzer.getJar().setManifest(manifest);
                if (analyzer.save(outputJar.toFile(), true)) {
                    log("Saved!\n");
                } else {
                    warn("Failed to create jar \n");
                    return false;
                }
            } else {
                warn("Analyzer Errors:\n%s\n", analyzer.getErrors());
                return false;
            }

            analyzer.close();

            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }

    private static void addLocalPackages(File outputDirectory, Analyzer analyzer) throws IOException {
        Packages packages = new Packages();

        if (outputDirectory != null && outputDirectory.isDirectory()) {
            // scan classes directory for potential packages
            DirectoryScanner scanner = new DirectoryScanner();
            scanner.setBasedir(outputDirectory);
            scanner.setIncludes(new String[]
                                        {"**/*.class"});

            scanner.addDefaultExcludes();
            scanner.scan();

            String[] paths = scanner.getIncludedFiles();
            for (int i = 0; i < paths.length; i++) {
                packages.put(analyzer.getPackageRef(getPackageName(paths[i])));
            }
        }

        Packages exportedPkgs = new Packages();
        Packages privatePkgs = new Packages();

        boolean noprivatePackages = "!*".equals(analyzer.getProperty(Analyzer.PRIVATE_PACKAGE));

        for (Descriptors.PackageRef pkg : packages.keySet()) {
            // mark all source packages as private by default (can be overridden by export list)
            privatePkgs.put(pkg);

            // we can't export the default package (".") and we shouldn't export internal packages
            String fqn = pkg.getFQN();
            if (noprivatePackages || !(".".equals(fqn) || fqn.contains(".internal") || fqn.contains(".impl"))) {
                exportedPkgs.put(pkg);
            }
        }

        Properties properties = analyzer.getProperties();
        String exported = properties.getProperty(Analyzer.EXPORT_PACKAGE);
        if (exported == null) {
            if (!properties.containsKey(Analyzer.EXPORT_CONTENTS)) {
                // no -exportcontents overriding the exports, so use our computed list
                for (Attrs attrs : exportedPkgs.values()) {
                    attrs.put(Constants.SPLIT_PACKAGE_DIRECTIVE, "merge-first");
                }
                properties.setProperty(Analyzer.EXPORT_PACKAGE, Processor.printClauses(exportedPkgs));
            } else {
                // leave Export-Package empty (but non-null) as we have -exportcontents
                properties.setProperty(Analyzer.EXPORT_PACKAGE, "");
            }
        }

        String internal = properties.getProperty(Analyzer.PRIVATE_PACKAGE);
        if (internal == null) {
            if (!privatePkgs.isEmpty()) {
                for (Attrs attrs : privatePkgs.values()) {
                    attrs.put(Constants.SPLIT_PACKAGE_DIRECTIVE, "merge-first");
                }
                properties.setProperty(Analyzer.PRIVATE_PACKAGE, Processor.printClauses(privatePkgs));
            } else {
                // if there are really no private packages then use "!*" as this will keep the Bnd Tool happy
                properties.setProperty(Analyzer.PRIVATE_PACKAGE, "!*");
            }
        }
    }

    private static String getPackageName(String filename) {
        int n = filename.lastIndexOf(File.separatorChar);
        return n < 0 ? "." : filename.substring(0, n).replace(File.separatorChar, '.');
    }

    private boolean isWab() {
        return webContext != null;
    }

    private void doWabStaging(Analyzer analyzer) throws Exception {
        if (!isWab()) {
            return;
        }
        String wab = analyzer.getProperty(analyzer.WAB);
        Jar dot = analyzer.getJar();

        log("wab %s", wab);
        analyzer.setBundleClasspath("WEB-INF/classes," +
                                            analyzer.getProperty(analyzer.BUNDLE_CLASSPATH));

        Set<String> paths = new HashSet<>(dot.getResources().keySet());

        for (String path : paths) {
            if (path.indexOf('/') > 0 && !Character.isUpperCase(path.charAt(0))) {
                log("wab: moving: %s", path);
                dot.rename(path, "WEB-INF/classes/" + path);
            }
        }

        Path wabRoot = Paths.get(wab);
        includeFiles(dot, null, wabRoot.toString());
    }

    /**
     * Parse the Bundle-Includes header. Files in the bundles Include header are
     * included in the jar. The source can be a directory or a file.
     *
     * @throws Exception
     */
    private void doIncludeResources(Analyzer analyzer) throws Exception {
        String includes = analyzer.getProperty(Analyzer.INCLUDE_RESOURCE);
        if (includes == null) {
            return;
        }
        Parameters clauses = analyzer.parseHeader(includes);
        Jar jar = analyzer.getJar();

        for (Map.Entry<String, Attrs> entry : clauses.entrySet()) {
            String name = entry.getKey();
            Map<String, String> extra = entry.getValue();
            // TODO consider doing something with extras

            String[] parts = name.split("\\s*=\\s*");
            String source = parts[0];
            String destination = parts[0];
            if (parts.length == 2) {
                source = parts[1];
            }

            includeFiles(jar, destination, source);
        }
    }

    private void includeFiles(Jar jar, String destinationRoot, String sourceRoot)
            throws IOException {

        Path classesBasedPath = classesDir.resolve(sourceRoot);
        Path sourceBasedPath = sourcesDir.resolve(sourceRoot);

        File classFile = classesBasedPath.toFile();
        File sourceFile = sourceBasedPath.toFile();

        if (classFile.isFile()) {
            addFileToJar(jar, destinationRoot, classesBasedPath.toAbsolutePath().toString());
        } else if (sourceFile.isFile()) {
            addFileToJar(jar, destinationRoot, sourceBasedPath.toAbsolutePath().toString());
        } else if (classFile.isDirectory()) {
            includeDirectory(jar, destinationRoot, classesBasedPath);
        } else if (sourceFile.isDirectory()) {
            includeDirectory(jar, destinationRoot, sourceBasedPath);
        } else {
            warn("Skipping resource in bundle %s: %s (File Not Found)\n",
                 bundleSymbolicName, sourceRoot);
        }
    }

    private void includeDirectory(Jar jar, String destinationRoot, Path sourceRoot)
            throws IOException {
        // iterate through sources
        // put each source on the jar
        FileVisitor<Path> visitor = new SimpleFileVisitor<Path>() {
            @Override
            public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException {
                Path relativePath = sourceRoot.relativize(file);
                String destination = destinationRoot != null ?
                        destinationRoot + "/" + relativePath.toString() : //TODO
                        relativePath.toString();

                addFileToJar(jar, destination, file.toAbsolutePath().toString());
                return FileVisitResult.CONTINUE;
            }
        };

        walkFileTree(sourceRoot, visitor);
    }

    private boolean addFileToJar(Jar jar, String destination, String sourceAbsPath) {
        if (includedResources.contains(sourceAbsPath)) {
            log("Skipping already included resource: %s\n", sourceAbsPath);
            return false;
        }
        File file = new File(sourceAbsPath);
        if (!file.isFile()) {
            throw new RuntimeException(
                    String.format("Skipping non-existent file: %s\n", sourceAbsPath));
        }
        Resource resource = new FileResource(file);
        if (jar.getResource(destination) != null) {
            warn("Skipping duplicate resource: %s\n", destination);
            return false;
        }
        jar.putResource(destination, resource);
        includedResources.add(sourceAbsPath);
        log("Adding resource: %s\n", destination);
        return true;
    }

    private void log(String format, Object... objects) {
        //System.err.printf(format, objects);
    }

    private void warn(String format, Object... objects) {
        stderr.printf(format, objects);
    }

    @Override
    public String toString() {
        return MoreObjects.toStringHelper(this)
                .add("inputJar", inputJar)
                .add("outputJar", outputJar)
                .add("classpath", classpath)
                .add("bundleName", bundleName)
                .add("groupId", groupId)
                .add("bundleSymbolicName", bundleSymbolicName)
                .add("bundleVersion", bundleVersion)
                .add("bundleDescription", bundleDescription)
                .add("bundleLicense", bundleLicense)
                .toString();
    }

    @Override
    public StepExecutionResult execute(ExecutionContext executionContext)
            throws IOException, InterruptedException {
        stderr = executionContext.getStdErr();
        boolean success = execute();
        stderr = System.err;
        return success ? StepExecutionResult.SUCCESS : StepExecutionResult.ERROR;
    }

    @Override
    public String getShortName() {
        return "osgiwrap";
    }

    @Override
    public String getDescription(ExecutionContext executionContext) {
        return "osgiwrap"; //FIXME
    }
}
