/*
 * 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.devtools.build.lib.worker.WorkerProtocol
import io.bazel.kotlin.builder.utils.rootCause
import java.io.*
import java.nio.charset.StandardCharsets.UTF_8
import java.nio.file.Files
import java.nio.file.Paths
import java.util.stream.Collectors

/**
 * Bazel worker runner.
 *
 *
 *
 * This class adapts a traditional command line program so it can be spawned by Bazel as a
 * persistent worker process that handles multiple invocations per JVM. It will also be backwards
 * compatible with being run as a normal single-invocation command.
 *
 * @param <T> delegate program type
</T> */
class BazelWorker<T : CommandLineProgram>(private val delegate: T, private val output: PrintStream, private val mnemonic: String) : CommandLineProgram {
    companion object {
        private const val INTERUPTED_STATUS = 0
        private const val ERROR_STATUS = 1
    }

    override fun apply(args: List<String>): Int {
        return if (args.contains("--persistent_worker"))
            runAsPersistentWorker(args)
        else delegate.apply(loadArguments(args, false))
    }

    @Suppress("UNUSED_PARAMETER")
    private fun runAsPersistentWorker(ignored: List<String>): Int {
        val realStdIn = System.`in`
        val realStdOut = System.out
        val realStdErr = System.err
        try {
            ByteArrayInputStream(ByteArray(0)).use { emptyIn ->
                ByteArrayOutputStream().use { buffer ->
                    PrintStream(buffer).use { ps ->
                        System.setIn(emptyIn)
                        System.setOut(ps)
                        System.setErr(ps)
                        while (true) {
                            val request = WorkerProtocol.WorkRequest.parseDelimitedFrom(realStdIn) ?: return 0
                            var exitCode: Int

                            exitCode = try {
                                delegate.apply(loadArguments(request.argumentsList, true))
                            } catch (e: RuntimeException) {
                                if (wasInterrupted(e)) {
                                    return INTERUPTED_STATUS
                                }
                                System.err.println(
                                        "ERROR: Worker threw uncaught exception with args: " + request.argumentsList.stream().collect(Collectors.joining(" ")))
                                e.printStackTrace(System.err)
                                ERROR_STATUS
                            }

                            WorkerProtocol.WorkResponse.newBuilder()
                                    .setOutput(buffer.toString())
                                    .setExitCode(exitCode)
                                    .build()
                                    .writeDelimitedTo(realStdOut)
                            realStdOut.flush()
                            buffer.reset()
                            System.gc()  // be a good little worker process and consume less memory when idle
                        }
                    }
                }
            }
        } catch (e: IOException) {
            if (wasInterrupted(e)) {
                return INTERUPTED_STATUS
            }
            throw e
        } catch (e: RuntimeException) {
            if (wasInterrupted(e)) {
                return INTERUPTED_STATUS
            }
            throw e
        } finally {
            System.setIn(realStdIn)
            System.setOut(realStdOut)
            System.setErr(realStdErr)
        }
        throw RuntimeException("drop through")
    }

    private fun loadArguments(args: List<String>, isWorker: Boolean): List<String> {
        if (args.isNotEmpty()) {
            val lastArg = args[args.size - 1]

            if (lastArg.startsWith("@")) {
                val pathElement = lastArg.substring(1)
                val flagFile = Paths.get(pathElement)
                if (isWorker && lastArg.startsWith("@@") || Files.exists(flagFile)) {
                    if (!isWorker && !mnemonic.isEmpty()) {
                        output.printf(
                                "HINT: %s will compile faster if you run: " + "echo \"build --strategy=%s=worker\" >>~/.bazelrc\n",
                                mnemonic, mnemonic)
                    }
                    try {
                        return Files.readAllLines(flagFile, UTF_8)
                    } catch (e: IOException) {
                        throw RuntimeException(e)
                    }

                }
            }
        }
        return args
    }

    private fun wasInterrupted(e: Throwable): Boolean {
        val cause = e.rootCause
        if (cause is InterruptedException || cause is InterruptedIOException) {
            output.println("Terminating worker due to interrupt signal")
            return true
        }
        return false
    }
}
