/*
 * 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

import com.google.common.collect.ImmutableList
import com.google.inject.Inject
import com.google.inject.Singleton
import io.bazel.kotlin.builder.mode.jvm.KotlinJvmCompilationExecutor
import io.bazel.kotlin.builder.utils.ArgMap
import io.bazel.kotlin.builder.utils.ArgMaps
import io.bazel.kotlin.model.KotlinModel
import java.nio.file.Files
import java.nio.file.Paths

@Singleton
@Suppress("MemberVisibilityCanBePrivate")
class KotlinBuilder @Inject internal constructor(
    private val commandBuilder: BuildCommandBuilder,
    private val jarToolInvoker: KotlinToolchain.JarToolInvoker,
    private val compilationExector: KotlinJvmCompilationExecutor
) : CommandLineProgram {
    fun execute(command: KotlinModel.BuilderCommand): Int =
        prepareForExecution(command).let { doExecute(it) }

    fun execute(args: List<String>): Int =
        execute(ArgMaps.from(args))

    fun execute(args: ArgMap): Int =
        prepareForExecution(commandBuilder.fromInput(args)).let {
            execute(it)
        }


    private fun doExecute(command: KotlinModel.BuilderCommand): Int {
        return try {
            compilationExector.compile(command)
            // gets basic timings on the tasks - create a better interface for this. and remove the line.
            // println(res.command.info.label + "\n" + res.timings.joinToString("\n"))
            0
        } catch (ex: CompilationStatusException) {
            ex.lines.forEach { println(it) }
            return ex.status
        }
    }

    private fun prepareForExecution(originalCommand: KotlinModel.BuilderCommand): KotlinModel.BuilderCommand {
        ensureOutputDirectories(originalCommand)
        return commandBuilder.withSources(originalCommand, unpackSources(originalCommand))
    }

    private fun ensureOutputDirectories(command: KotlinModel.BuilderCommand) {
        Files.createDirectories(Paths.get(command.outputs.classDirectory))
        Files.createDirectories(Paths.get(command.outputs.tempDirectory))
        Files.createDirectories(Paths.get(command.outputs.sourceGenDir))
    }

    private fun unpackSources(command: KotlinModel.BuilderCommand): Iterator<String> {
        if (command.inputs.sourceJarsList.isEmpty()) {
            ImmutableList.of<String>().iterator()
        }

        val sourceUnpackDirectory =
            Paths.get(command.outputs.tempDirectory).let {
                it.resolve("_srcjars").toFile().let {
                    try {
                        it.mkdirs(); it
                    } catch (ex: Exception) {
                        throw RuntimeException("could not create unpack directory at $it", ex)
                    }
                }
            }

        for (sourceJar in command.inputs.sourceJarsList) {
            jarToolInvoker.invoke(listOf("xf", Paths.get(sourceJar).toAbsolutePath().toString()), sourceUnpackDirectory)
        }

        return sourceUnpackDirectory
            .walk()
            .filter { it.name.endsWith(".kt") || it.name.endsWith(".java") }
            .map { it.toString() }
            .iterator()
    }

    override fun apply(args: List<String>): Int {
        return execute(args)
    }

    companion object {
        @JvmStatic
        fun main(args: Array<String>) {
            val worker = KotlinToolchain.createInjector(System.err).getInstance(BazelWorker::class.java)
            System.exit(worker.apply(args.toList()))
        }
    }
}
