/*
 * Copyright 2018 The Bazel Authors. All rights reserved.
 *
 * 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 io.bazel.ruleskotlin.workers

import io.bazel.ruleskotlin.workers.utils.resolveVerified
import io.bazel.ruleskotlin.workers.utils.verifiedRelativeFiles
import org.jetbrains.kotlin.preloading.ClassPreloadingUtils
import org.jetbrains.kotlin.preloading.Preloader
import java.io.PrintStream
import java.nio.file.Path
import java.nio.file.Paths

@Suppress("PropertyName")
class KotlinToolchain {
    companion object {
        internal val JAVA_HOME = Paths.get("external", "local_jdk")
        internal val KOTLIN_HOME = Paths.get("external", "com_github_jetbrains_kotlin")

        internal val NO_ARGS = arrayOf<Any>()
    }

    val JAVAC_PATH = JAVA_HOME.resolveVerified("bin", "javac").toString()
    val JAR_TOOL_PATH = JAVA_HOME.resolveVerified("bin", "jar").toString()
    val JDEPS_PATH = JAVA_HOME.resolveVerified("bin", "jdeps").toString()
    val KOTLIN_LIB_DIR: Path = KOTLIN_HOME.resolveVerified("lib").toPath()

    private val kotlinPreloadJars = KOTLIN_LIB_DIR.verifiedRelativeFiles(
            Paths.get("kotlin-compiler.jar")
    )

    val KOTLIN_STD_LIBS = arrayOf(
            "kotlin-stdlib.jar",
            "kotlin-stdlib-jdk7.jar",
            "kotlin-stdlib-jdk8.jar"
    )

    private val classLoader: ClassLoader by lazy {
        ClassPreloadingUtils.preloadClasses(
                kotlinPreloadJars,
                Preloader.DEFAULT_CLASS_NUMBER_ESTIMATE,
                Thread.currentThread().contextClassLoader,
                null
        )
    }

    interface KotlinCompiler {
        fun compile(args: Array<String>, out: PrintStream): Int
    }

    /**
     * Load the Kotlin compiler into a Preloading classLoader.
     */
    val kotlinCompiler: KotlinCompiler by lazy {
        val compilerClass = classLoader.loadClass("org.jetbrains.kotlin.cli.jvm.K2JVMCompiler")
        val exitCodeClass = classLoader.loadClass("org.jetbrains.kotlin.cli.common.ExitCode")

        val compiler = compilerClass.newInstance()
        val execMethod = compilerClass.getMethod("exec", PrintStream::class.java, Array<String>::class.java)
        val getCodeMethod = exitCodeClass.getMethod("getCode")

        object : KotlinCompiler {
            override fun compile(args: Array<String>, out: PrintStream): Int {
                val exitCodeInstance: Any
                try {
                    exitCodeInstance = execMethod.invoke(compiler, out, args)
                    return getCodeMethod.invoke(exitCodeInstance, *NO_ARGS) as Int
                } catch (e: Exception) {
                    throw RuntimeException(e)
                }
            }
        }
    }
}


