/*
 * 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.kotlin.builder.mode.jvm.actions


import io.bazel.kotlin.builder.BuildAction
import io.bazel.kotlin.builder.CompileResult
import io.bazel.kotlin.builder.Context
import io.bazel.kotlin.builder.KotlinToolchain
import io.bazel.kotlin.builder.mode.jvm.utils.KotlinCompilerOutputProcessor
import io.bazel.kotlin.builder.model.CompileDirectories
import io.bazel.kotlin.builder.model.CompilePluginConfig
import io.bazel.kotlin.builder.model.Flags
import io.bazel.kotlin.builder.model.Metas
import io.bazel.kotlin.builder.utils.addAll
import io.bazel.kotlin.builder.utils.annotationProcessingGeneratedJavaSources
import io.bazel.kotlin.builder.utils.moduleName

// The Kotlin compiler is not suited for javac compilation as of 1.2.21. The errors are not conveyed directly and would need to be preprocessed, also javac
// invocations Configured via Kotlin use eager analysis in some corner cases this can result in classpath exceptions from the Java Compiler..
class KotlinMainCompile(toolchain: KotlinToolchain) : BuildAction("compile kotlin classes", toolchain) {
    companion object {
        /**
         * Default fields that are directly mappable to kotlin compiler args.
         */
        private val COMPILE_MAPPED_FLAGS = arrayOf(
                Flags.CLASSPATH,
                Flags.KOTLIN_API_VERSION,
                Flags.KOTLIN_LANGUAGE_VERSION,
                Flags.KOTLIN_JVM_TARGET)

        val Result = CompileResult.Meta("kotlin_compile_result")
    }

    /**
     * Evaluate the compilation context and add Metadata to the ctx if needed.
     *
     * @return The args to pass to the kotlin compile class.
     */
    private fun setupCompileContext(ctx: Context): MutableList<String> {
        val args = mutableListOf<String>()
        val compileDirectories = CompileDirectories[ctx]

        ctx.copyOfFlags(*COMPILE_MAPPED_FLAGS).forEach { field, arg ->
            args.add(field.kotlinFlag!!); args.add(arg)
        }

        args
                .addAll("-module-name", ctx.moduleName)
                .addAll("-d", compileDirectories.classes.toString())

        Flags.KOTLIN_PASSTHROUGH_FLAGS[ctx]?.takeIf { it.isNotBlank() }?.also { args.addAll(it.split(" ")) }

        return args
    }

    override fun invoke(ctx: Context): Int {
        val commonArgs = setupCompileContext(ctx)
        val sources = Metas.ALL_SOURCES.mustGet(ctx)
        val pluginStatus = CompilePluginConfig[ctx]

        // run a kapt generation phase if needed.
        if (pluginStatus.hasAnnotationProcessors) {
            invokeCompilePhase(
                    args = mutableListOf(*commonArgs.toTypedArray()).let {
                        it.addAll(pluginStatus.args)
                        it.addAll(sources)
                        it.toTypedArray()
                    },
                    onNonTeminalExitCode = { outputProcessors, exitCode ->
                        outputProcessors.process()
                        exitCode
                    }
            ).takeIf { it != 0 }?.also { return it }
        }
        return invokeCompilePhase(
                args = commonArgs.let { args ->
                    args.addAll(sources)
                    ctx.annotationProcessingGeneratedJavaSources()?.also { args.addAll(it) }
                    args.toTypedArray()
                },
                onNonTeminalExitCode = { outputProcessor, exitCode ->
                    // give javac a chance to process the java sources.
                    Result[ctx] = CompileResult.deferred(exitCode) { _ ->
                        outputProcessor.process()
                        exitCode
                    }
                    0
                }
        )
    }

    private fun invokeCompilePhase(args: Array<String>, onNonTeminalExitCode: (KotlinCompilerOutputProcessor, Int) -> Int): Int {
        val outputProcessor = KotlinCompilerOutputProcessor.ForKotlinC(System.out)

        val exitCode = try {
            toolchain.kotlinCompiler.compile(args, outputProcessor.collector)
        } catch (ex: Exception) {
            outputProcessor.process()
            throw ex
        }

        if (exitCode < 2) {
            // 1 is a standard compilation error
            // 2 is an internal error
            // 3 is the script execution error
            return onNonTeminalExitCode(outputProcessor, exitCode)
        } else {
            outputProcessor.process()
            throw RuntimeException("KotlinMainCompile returned terminal error code: $exitCode")
        }
    }
}
