// Path: falchion-container/src/main/java/net/unit8/falchion/monitor/JvmMonitor.java
// public interface JvmMonitor {
//     void start(JvmProcess process);
//     MonitorStat getStat();
//     void stop();
// }
// 
// Path: falchion-container/src/main/java/net/unit8/falchion/monitor/MonitorStat.java
// public interface MonitorStat {
//     JsonObject toJson();
// }


import net.unit8.falchion.monitor.JvmMonitor;
import net.unit8.falchion.monitor.MonitorStat;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.File;
import java.io.IOException;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.concurrent.Callable;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

    public String getMainClass() {
        return mainClass;
    }

    public void addMonitor(JvmMonitor... monitors) {
        this.monitors.addAll(Arrays.asList(monitors));
    }

    public void kill() throws IOException {
        try {
            Process killProcess = new ProcessBuilder("kill", "-TERM", Long.toString(pid)).start();
            int killResult = killProcess.waitFor();
            if (killResult != 0)
                throw new IOException("kill " + pid + " is failure");
        } catch (InterruptedException ex) {
            LOG.warn("Kill the process (pid={}) is canceled.", pid);
        }
    }

    public void setIoDir(File directory) {
        if (process != null) {
            throw new IllegalStateException("You should call setIoDir before starting process");
        }
        String prefix = fmtIO.format(LocalDateTime.now()) + "." + id;
        processBuilder
                .redirectError(new File(directory, prefix + ".err"))
                .redirectOutput(new File(directory, prefix + ".out"));
    }

// Path: falchion-container/src/main/java/net/unit8/falchion/monitor/JvmMonitor.java
// public interface JvmMonitor {
//     void start(JvmProcess process);
//     MonitorStat getStat();
//     void stop();
// }
// 
// Path: falchion-container/src/main/java/net/unit8/falchion/monitor/MonitorStat.java
// public interface MonitorStat {
//     JsonObject toJson();
// }


// Path: falchion-container/src/main/java/net/unit8/falchion/JvmProcess.java
import net.unit8.falchion.monitor.JvmMonitor;
import net.unit8.falchion.monitor.MonitorStat;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.File;
import java.io.IOException;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.concurrent.Callable;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;


    public String getMainClass() {
        return mainClass;
    }

    public void addMonitor(JvmMonitor... monitors) {
        this.monitors.addAll(Arrays.asList(monitors));
    }

    public void kill() throws IOException {
        try {
            Process killProcess = new ProcessBuilder("kill", "-TERM", Long.toString(pid)).start();
            int killResult = killProcess.waitFor();
            if (killResult != 0)
                throw new IOException("kill " + pid + " is failure");
        } catch (InterruptedException ex) {
            LOG.warn("Kill the process (pid={}) is canceled.", pid);
        }
    }

    public void setIoDir(File directory) {
        if (process != null) {
            throw new IllegalStateException("You should call setIoDir before starting process");
        }
        String prefix = fmtIO.format(LocalDateTime.now()) + "." + id;
        processBuilder
                .redirectError(new File(directory, prefix + ".err"))
                .redirectOutput(new File(directory, prefix + ".out"));
    }

    public List<MonitorStat> getMonitorStats() {