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


import com.google.protobuf.MessageOrBuilder
import com.google.protobuf.TextFormat
import io.bazel.kotlin.model.CompilationTaskInfo
import java.io.File
import java.io.PrintStream
import java.nio.file.Paths

class CompilationTaskContext(val info: CompilationTaskInfo, private val out: PrintStream) {
    private val executionRoot: String = Paths.get("").toAbsolutePath().toString() + File.separator
    private val timings: MutableList<String>?
    @PublishedApi
    internal val isTracing: Boolean

    init {
        val debugging = info.debugList.toSet()
        timings = if (debugging.contains("timings")) mutableListOf() else null
        isTracing = debugging.contains("trace")
    }

    fun reportUnhandledException(throwable: Throwable) { throwable.printStackTrace(out) }

    /**
     * Print a list of debugging lines.
     *
     * @param header a header string
     * @param lines a list of lines to print out
     * @param prefix a prefix to add to each line
     * @param filterEmpty if empty lines should be discarded or not
     */
    fun printLines(header: String, lines: List<String>, prefix: String = "|  ", filterEmpty: Boolean = false) {
        check(header.isNotEmpty())
        out.println(if (header.endsWith(":")) header else "$header:")
        lines.forEach {
            if (it.isNotEmpty() || !filterEmpty) {
                out.println("$prefix$it")
            }
        }
        out.println()
    }

    inline fun <T> whenTracing(block: CompilationTaskContext.() -> T): T? {
        return if(isTracing) { block() } else null
    }

    /**
     * Print a proto message if debugging is enabled for the task.
     */
    fun printProto(header: String, msg: MessageOrBuilder) {
        printLines(header, TextFormat.printToString(msg).split("\n"), filterEmpty = true)
    }

    /**
     * This method normalizes and reports the output from the Kotlin compiler.
     */
    fun printCompilerOutput(lines: List<String>) {
        lines.map(::trimExecutionRootPrefix).forEach(out::println)
    }

    private fun trimExecutionRootPrefix(toPrint: String): String {
        // trim off the workspace component
        return if (toPrint.startsWith(executionRoot)) {
            toPrint.replaceFirst(executionRoot, "")
        } else toPrint
    }

    /**
     * Runs a task and records the timings.
     */
    fun <T> execute(name: String, task: () -> T): T {
        return if (timings == null) {
            task()
        } else {
            val start = System.currentTimeMillis()
            try {
                task()
            } finally {
                val stop = System.currentTimeMillis()
                timings += "$name: ${stop - start} ms"
            }
        }
    }

    /**
     * This method should be called at the end of builder invocation.
     *
     * @param succesfull true if the task finished succesfully.
     */
    fun finalize(succesfull: Boolean) {
        if(succesfull) {
            timings?.also { printLines("Task timings", it, prefix = "  * ") }
        }
    }
}
