package nextflow.k8s

import groovy.util.logging.Slf4j

import java.nio.file.Files
import java.nio.file.Path

@Slf4j
class K8sRuntimeRecorder {
    private final boolean enabled
    private final String recordPath

    private ArrayList<K8sRuntimeRecord> records

    K8sRuntimeRecorder(boolean enabled, String recordPath) {
        this.enabled = enabled
        this.recordPath = recordPath
        this.records = new ArrayList<>()
    }

    /**
     * Records the runtime of a task.
     * This should be called for a finished task, which has its
     * start and end timestamps set.
     * @param task
     */
    synchronized void record(K8sTaskHandler task) {
        if (!enabled)
            return;
        long runtimeMilis = task.completeTimeMillis - task.startTimeMillis
        long inputSizeSum = 0

        // Input files
        def inputFiles = task.task.getInputFilesMap()
        for (Map.Entry<String, Path> f : inputFiles) {
            try {
                inputSizeSum += Files.size(f.value)
            } catch (IOException ex) {
                log.error "[K8s] failed to get size of input file ${f.value} of task ${task.task.name}: ${ex.message}"
            }
        }

        // Non file input
        def inputs = task.task.getInputs()
        for (Map.Entry i : inputs) {
            inputSizeSum += i.value.toString().length()
        }

        records.add(new K8sRuntimeRecord(task.task.processor.name, inputSizeSum, runtimeMilis))
    }

    void write() {
        if (!enabled)
            return;
        try {
            FileWriter out = new FileWriter(recordPath)
            for (K8sRuntimeRecord record : records) {
                out.write("${record.taskName},${record.inputSize},${record.runtimeMillis}\n")
            }
            out.close()
            log.info "[K8s] written runtime recording to ${recordPath}"
        } catch (IOException err) {
            log.error "[K8s] failed to write runtime recording ${recordPath}: ${err.message}"
        }
    }
}
