package org.implab.gradle.common.exec;

import java.io.IOException;
import java.util.List;
import java.util.concurrent.CompletableFuture;
import java.util.function.Consumer;

/** Shell used to start processes */
public interface ExecShell {

    /** Creates new process builder {@link ExecBuilder} */
    ExecBuilder executable();

    /**
     * Creates default process execution "shell" which will execute processes
     * directly.
     */
    static ExecShell system() {
        return () -> new SystemExecBuilder();
    }

    /**
     * Creates a stub shell which will print command to STDERR and return 0 (no
     * error).
     */
    static ExecShell echoStderr() {
        return () -> new EchoExecBuilder(true);
    }

    /**
     * Creates a stub shell which will print command to STDOUT and return 0 (no
     * error).
     */

    static ExecShell echo() {
        return () -> new EchoExecBuilder(false);
    }

    /**
     * Creates a stub shell which will call the specified consumer and will supply a
     * command line to it.
     * The command line will be passed as a list of strings.
     * 
     * @param consumer The consumer fot the command line
     * @return
     */
    static ExecShell echo(Consumer<List<String>> consumer) {
        return () -> new ExecBuilder() {
            @Override
            protected CompletableFuture<Integer> startInternal(
                    CommandSpec command,
                    EnvironmentSpec environment,
                    PipeSpec redirect) throws IOException {
                consumer.accept(command.commandLine());
                return CompletableFuture.completedFuture(0);
            }
        };
    }
}
