package org.implab.gradle.common.exec;

import java.io.File;
import java.io.IOException;
import java.lang.ProcessBuilder.Redirect;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.concurrent.CompletableFuture;

class SystemExecBuilder extends ExecBuilder {
    @Override
    protected CompletableFuture<Integer> startInternal(Map<String, String> environment, File directory,
            List<String> commandLine, Optional<RedirectFrom> stdinRedirect, Optional<RedirectTo> stdoutRedirect,
            Optional<RedirectTo> stderrRedirect) throws IOException {

        var builder = new ProcessBuilder(commandLine)
                .directory(directory);

        builder.environment().putAll(environment);

        // TODO Auto-generated method stub
        var tasks = new ArrayList<CompletableFuture<?>>();

        if (!stdoutRedirect.isPresent())
            builder.redirectOutput(Redirect.DISCARD);
        if (!stderrRedirect.isPresent())
            builder.redirectError(Redirect.DISCARD);

        // run process
        var proc = builder.start();

        tasks.add(proc.onExit());

        stdinRedirect.map(from -> from.redirect(proc.getOutputStream())).ifPresent(tasks::add);
        stdoutRedirect.map(to -> to.redirect(proc.getInputStream())).ifPresent(tasks::add);
        stderrRedirect.map(to -> to.redirect(proc.getErrorStream())).ifPresent(tasks::add);

        return CompletableFuture
                .allOf(tasks.toArray(new CompletableFuture<?>[0]))
                .thenApply(t -> proc.exitValue());
    }
}
