// Defines tasks for building the VDL tool and generating VDL files.

package io.v.vdl

import org.gradle.api.InvalidUserDataException
import org.gradle.api.Plugin
import org.gradle.api.Project
import org.gradle.api.artifacts.ProjectDependency
import org.gradle.api.file.FileCollection
import org.gradle.api.tasks.Copy
import org.gradle.api.tasks.Delete
import org.gradle.api.tasks.Exec
import org.gradle.language.jvm.tasks.ProcessResources

import java.util.jar.JarEntry
import java.util.jar.JarFile

class VdlPlugin implements Plugin<Project> {
    void apply(Project project) {
        project.extensions.create('vdl', VdlConfiguration)

        def extractTask = project.task('extractVdl', type: Copy) {
            from {
                getVdlToolJarFiles(project, project.buildscript.configurations.classpath)
            }
            into { new File(project.buildDir, 'vdltool') }
        }
        def clearVdlOutputTask = project.task('clearVdlOutput', type: Delete) {
            delete { project.vdl.outputPath }
            delete { project.vdl.transitiveVdlDir }
        }
        def generateTask = project.task('generateVdl', type: Exec) {
        }
        def vdlTask = project.task('vdl') {
            group = "Build"
            description('Generates Java vdl source using the vdl tool')
        }
        def prepareTask = project.task('prepareVdl') {
            doLast {
                List<String> vdlPaths = extractTransitiveVdlFilesAndGetInputPaths(project).asList()
                List<String> outDirs = getJavaOutDirs(project)

                generateTask.environment(VDLROOT: getVdlRootPath(project))
                generateTask.environment(VDLPATH: vdlPaths.join(":"))
                List<String> commandLine = ['build/vdltool/vdl-' + getOsName(),
                                            'generate',
                                            '--lang=java',
                                            '--java-out-dir=' + outDirs.join(",")
                ]
                if (!project.vdl.packageTranslations.isEmpty()) {
                    commandLine.add('--java-out-pkg=' + project.vdl.packageTranslations.join(','))
                }
                commandLine.add('all')
                generateTask.commandLine(commandLine)
            }
        }
        def removeVdlRootTask = project.task('removeVdlRoot', type: Delete) {
            onlyIf { !project.vdl.generateVdlRoot }
            delete { project.vdl.outputPath + '/io/v/v23/vdlroot/' }
        }
        extractTask.dependsOn(prepareTask)
        generateTask.dependsOn(clearVdlOutputTask)
        generateTask.dependsOn(extractTask)
        removeVdlRootTask.dependsOn(generateTask)
        vdlTask.dependsOn(removeVdlRootTask)

        if (project.vdl.formatGeneratedVdl) {
            def formatTask = project.task('formatGeneratedVdlFiles', type: FormatTask) {
                format project.fileTree({ project.vdl.outputPath }).include('**/*.java')
            }
            formatTask.dependsOn(removeVdlRootTask)
            vdlTask.dependsOn(formatTask)
        }
        if (project.plugins.hasPlugin('com.android.library')
                || project.plugins.hasPlugin('com.android.application')) {
            project.tasks.'preBuild'.dependsOn(vdlTask)
            project.android.sourceSets.main.java.srcDir({ project.vdl.outputPath })
        }

        if (project.plugins.hasPlugin('java')) {
            project.compileJava.dependsOn(vdlTask)
            project.sourceSets.main.java.srcDir({ project.vdl.outputPath })
        }

        if (project.hasProperty('clean')) {
            project.clean.delete({ project.vdl.outputPath })
            project.clean.delete({ project.vdl.transitiveVdlDir })
        }

        project.afterEvaluate({
            if (project.plugins.hasPlugin('java')) {
                // Add VDL files in VDL input paths to project resources.
                project.vdl.inputPaths.each {
                    project.sourceSets.main.resources.srcDirs(it).include('**/*.vdl')
                }

                // Ensure that empty directories are not copied.
                project.tasks.withType(ProcessResources, {
                    it.setIncludeEmptyDirs(false)
                })
            }
        })
    }

    public static String getVdlRootPath(Project project) {
        if (null == project.vdl.vdlRootPath || "".equals(project.vdl.vdlRootPath)) {
            // Look in the transitive VDL files, it should be there so long as the project depends
            // on VDL.
            File candidateVdlRoot = new File(
                    new File(project.getProjectDir(), project.vdl.transitiveVdlDir), 'v.io/v23/vdlroot')
            if (candidateVdlRoot.exists() && candidateVdlRoot.isDirectory()) {
                return candidateVdlRoot.getPath()
            }

            throw new InvalidUserDataException('could not determine a value for VDLROOT, '
                    + 'you should check to ensure your project depends on vanadium')
        } else {
            return project.vdl.vdlRootPath
        }
    }

    public static Set<String> extractTransitiveVdlFilesAndGetInputPaths(Project project) {
        Set<String> result = new LinkedHashSet<>(project.vdl.inputPaths)
        // Go through the dependencies of all configurations looking for jar files containing
        // VDL files.
        project.configurations.each({
            it.each({
                if (it.getName().endsWith('.jar') && it.exists()) {
                    if (extractVdlFiles(it, new File(project.getProjectDir(), project.vdl.transitiveVdlDir))) {
                        result.add(project.vdl.transitiveVdlDir)
                    }
                }
            })
        })

        // Now recursively descend through the project's project dependencies looking for
        // VDL projects.
        Set<String> projectInputPaths = new LinkedHashSet<>()
        addVdlInputPathsForProject(project, projectInputPaths)
        // Copy any VDL files in any input path to the transitive VDL directory.
        project.copy {
            projectInputPaths.each({
                from(it) {
                    include '**/*.vdl'
                    includeEmptyDirs = false
                }
            })

            into project.vdl.transitiveVdlDir
        }
        if (!projectInputPaths.isEmpty()) {
            result.add(project.vdl.transitiveVdlDir)
        }
        return result
    }

    public static List<String> getJavaOutDirs(Project project) {
        List<String> result = new ArrayList<>()
        for (String inputPath : project.vdl.inputPaths) {
            if (!inputPath.startsWith(project.vdl.transitiveVdlDir)) {
                result.add(inputPath + '->' + project.vdl.outputPath)
            }
        }
        result.add(project.vdl.transitiveVdlDir + "->" + project.vdl.transitiveVdlDir)
        return result
    }

    /**
     * Extracts any vdl files in the given jar file to the given destination directory. Returns
     * {@code true} if any files were extracted.
     */
    private static boolean extractVdlFiles(File jarFile, File destination) {
        JarFile jar = new JarFile(jarFile)
        Enumeration<JarEntry> entries = jar.entries()
        boolean extracted = false
        while (entries.hasMoreElements()) {
            JarEntry entry = entries.nextElement()
            if (entry.isDirectory() || !entry.getName().endsWith('.vdl')) {
                continue
            }
            // Create the file's directory.
            File destinationFile = new File(destination, entry.getName())
            destinationFile.getParentFile().mkdirs()
            InputStream input = jar.getInputStream(entry)
            OutputStream output = new FileOutputStream(destinationFile)
            copyStream(input, output)
            extracted = true
            input.close()
            output.close()
        }
        return extracted
    }

    private static void copyStream(InputStream source, OutputStream destination) {
        byte[] buffer = new byte[1 << 16]
        while (true) {
            int r = source.read(buffer)
            if (r == -1) {
                return
            }
            destination.write(buffer, 0, r)
        }
    }

    /**
     * Returns a list of {@link java.io.File} instances representing VDL binaries.
     */
    static List<File> getVdlToolJarFiles(Project project, FileCollection files) {
        List<File> result = new ArrayList<File>()

        for (File file : files.findAll({
            it.name.contains 'gradle-plugin'
        })) {
            project.zipTree(file).findAll({ it.name.startsWith("vdl-") }).each({
                result.add(project.resources.text.fromArchiveEntry(file, it.name).asFile())
            })
        }

        return result
    }

    private static void addVdlInputPathsForProject(Project project, Set<String> inputPaths) {
        if (project == null) {
            return
        }
        Object extension = project.extensions.findByName('vdl')
        if (extension != null) {
            extension.inputPaths.each {
                File newPath = new File(it)
                if (!newPath.isAbsolute()) {
                    newPath = new File(project.getProjectDir(), it)
                }
                inputPaths.add(newPath.getAbsolutePath())
            }
        }
        project.configurations.each({
            it.dependencies.each({
                if (it instanceof ProjectDependency) {
                    addVdlInputPathsForProject(it.getDependencyProject(), inputPaths)
                }
            })
        })
    }

    private static isMacOsX() {
        return System.properties['os.name'].toLowerCase().contains("os x")
    }

    private static isLinux() {
        return System.properties['os.name'].toLowerCase().contains("linux")
    }

    static String getOsName() {
        if (isLinux()) {
            return "linux";
        } else if (isMacOsX()) {
            return "macosx";
        } else {
            throw new IllegalStateException("Unsupported operating system " + System.properties.'os.name')
        }
    }
}

class VdlConfiguration {
    List<String> inputPaths = []
    String vdlRootPath = ""
    String outputPath = "generated-src/vdl"
    String transitiveVdlDir = "generated-src/transitive-vdl"
    String vdlToolPath = ""
    List<String> packageTranslations = ["v.io->io/v"]
    boolean formatGeneratedVdl = true

    // If true, code generated for the vdlroot vdl package will be emitted.
    // Typically, users will want to leave this set to false as they will
    // already get the vdlroot package by depending on the :lib project.
    boolean generateVdlRoot = false;
}

