/*
 * Copyright 2015-2016 IBM Corporation
 *
 * 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 actionContainers

import java.net.URI
import java.net.URLClassLoader
import java.nio.file.Files
import java.nio.file.Path
import java.nio.file.Paths
import java.nio.file.SimpleFileVisitor
import java.nio.file.FileVisitResult
import java.nio.file.FileSystems
import java.nio.file.attribute.BasicFileAttributes
import java.nio.charset.StandardCharsets
import java.util.Base64

import javax.tools.ToolProvider

import collection.JavaConverters._

/**
 * A collection of utility objects to create ephemeral action resources based
 *  on file contents.
 */
object ResourceHelpers {
    /** Creates a zip file based on the contents of a top-level directory. */
    object ZipBuilder {
        def mkBase64Zip(sources: Seq[(Seq[String], String)]): String = {
            val (tmpDir, _) = writeSourcesToTempDirectory(sources)
            val archive = makeZipFromDir(tmpDir)
            readAsBase64(archive)
        }
    }

    /**
     * A convenience object to compile and package Java sources into a JAR, and to
     * encode that JAR as a base 64 string. The compilation options include the
     * current classpath, which is why Google GSON is readily available (though not
     * packaged in the JAR).
     */
    object JarBuilder {
        def mkBase64Jar(sources: Seq[(Seq[String], String)]): String = {
            // Note that this pipeline doesn't delete any of the temporary files.
            val binDir = compile(sources)
            val jarPath = makeJarFromDir(binDir)
            val base64 = readAsBase64(jarPath)
            base64
        }

        def mkBase64Jar(source: (Seq[String], String)): String = {
            mkBase64Jar(Seq(source))
        }

        private def compile(sources: Seq[(Seq[String], String)]): Path = {
            require(!sources.isEmpty)

            // The absolute paths of the source file
            val (srcDir, srcAbsPaths) = writeSourcesToTempDirectory(sources)

            // A temporary directory for the destination files.
            val binDir = Files.createTempDirectory("bin").toAbsolutePath()

            // Preparing the compiler
            val compiler = ToolProvider.getSystemJavaCompiler()
            val fileManager = compiler.getStandardFileManager(null, null, StandardCharsets.UTF_8)

            // Collecting all files to be compiled
            val compUnit = fileManager.getJavaFileObjectsFromFiles(srcAbsPaths.map(_.toFile).asJava)

            // Setting the options
            val compOptions = Seq(
                "-d", binDir.toAbsolutePath().toString(),
                "-classpath", buildClassPath())
            val compTask = compiler.getTask(null, fileManager, null, compOptions.asJava, null, compUnit)

            // ...and off we go.
            compTask.call()

            binDir
        }

        private def buildClassPath(): String = {
            val bcp = System.getProperty("java.class.path")

            val list = this.getClass().getClassLoader() match {
                case ucl: URLClassLoader =>
                    bcp :: ucl.getURLs().map(_.getFile().toString()).toList

                case _ =>
                    List(bcp)
            }

            list.mkString(System.getProperty("path.separator"))
        }
    }

    /**
     * Creates a temporary directory and reproduces the desired file structure
     * in it. Returns the path of the temporary directory and the path of each
     * file as represented in it.
     */
    private def writeSourcesToTempDirectory(sources: Seq[(Seq[String], String)]): (Path, Seq[Path]) = {
        // A temporary directory for the source files.
        val srcDir = Files.createTempDirectory("src").toAbsolutePath()

        val srcAbsPaths = for ((sourceName, sourceContent) <- sources) yield {
            // The relative path of the source file
            val srcRelPath = Paths.get(sourceName.head, sourceName.tail: _*)
            // The absolute path of the source file
            val srcAbsPath = srcDir.resolve(srcRelPath)
            // Create parent directories if needed.
            Files.createDirectories(srcAbsPath.getParent)
            // Writing contents
            Files.write(srcAbsPath, sourceContent.getBytes(StandardCharsets.UTF_8))

            srcAbsPath
        }

        (srcDir, srcAbsPaths)
    }

    private def makeZipFromDir(dir: Path): Path = makeArchiveFromDir(dir, ".zip")

    private def makeJarFromDir(dir: Path): Path = makeArchiveFromDir(dir, ".jar")

    /**
     * Compresses all files beyond a directory into a zip file.
     * Note that Jar files are just zip files.
     */
    private def makeArchiveFromDir(dir: Path, extension: String): Path = {
        // Any temporary file name for the archive.
        val arPath = Files.createTempFile("output", extension).toAbsolutePath()

        // We "mount" it as a filesystem, so we can just copy files into it.
        val dstUri = new URI("jar:" + arPath.toUri().getScheme(), arPath.toAbsolutePath().toString(), null)
        // OK, that's a hack. Doing this because newFileSystem wants to create that file.
        arPath.toFile().delete()
        val fs = FileSystems.newFileSystem(dstUri, Map(("create" -> "true")).asJava)

        // Traversing all files in the bin directory...
        Files.walkFileTree(dir, new SimpleFileVisitor[Path]() {
            override def visitFile(path: Path, attributes: BasicFileAttributes) = {
                // The path relative to the src dir
                val relPath = dir.relativize(path)

                // The corresponding path in the zip
                val arRelPath = fs.getPath(relPath.toString())

                // If this file is not top-level in the src dir...
                if (relPath.getParent() != null) {
                    // ...create the directory structure if it doesn't exist.
                    if (!Files.exists(arRelPath.getParent())) {
                        Files.createDirectories(arRelPath.getParent())
                    }
                }

                // Finally we can copy that file.
                Files.copy(path, arRelPath)

                FileVisitResult.CONTINUE
            }
        })

        fs.close()

        arPath
    }

    /** Reads the contents of a (possibly binary) file into a base64-encoded String */
    def readAsBase64(path: Path): String = {
        val encoder = Base64.getEncoder()
        new String(encoder.encode(Files.readAllBytes(path)), StandardCharsets.UTF_8)
    }
}
