/*
 * Copyright 2016-present Open Networking Laboratory
 *
 * 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
        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);

            //analyzer.setBase(classesDir.toFile());

//            analyzer.setProperty("DESTDIR");
//            analyzer.setBase();

            // ------------- let's begin... -------------------------

            //Add local packges to jar file.
            addLocalPackages(new File(classesDir.toString()), analyzer);
//            analyzer.analyze();

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

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

            // Calculate the manifest
//            Manifest manifest = analyzer.calcManifest();
            //OutputStream s = new FileOutputStream("/tmp/foo2.txt");
            //manifest.write(s);
            //s.close();

            if (analyzer.isOk()) {
                //Build the jar files
                analyzer.build();
                Map<String, String> properties = Maps.newHashMap();

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

                //add calculated manifest file.
                Manifest manifest = analyzer.calcManifest();
                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
    }
}
