"""
A runner execute a program.
"""
import os.path
import subprocess

class RunnerError(Exception):
    pass

class Runner:
    def __init__(self, command):
        """A generic class to run a program

        Parameters:

        command: command to execute the program
        """
        self.command = command

    def run(self, cwd=None, env=None, stdin=None, stdout=None, stderr=None, shell=False, timeout=None):
        """Run the program

        raise CalledProcessError if the return error code is non-zero
        """
        subprocess.run(self.command, cwd=cwd, env=env, check=True, timeout=timeout,
                       stdin=stdin, stdout=stdout, stderr=stderr, shell=shell)

class RunnerMW(Runner):
    def __init__(self, mw, config=None, data=None, output_rank=None):
        """Runner for MW

        Parameters
        ----------
        mw : MW executable command
        config : path to configuration file
        data : path to data file
        output_rank : option to --output-rank
        """
        self.mw = mw
        self.config = config
        self.data = data
        self.output_rank = output_rank

        command = [mw]
        if config is not None:
            if not os.path.isfile(config):
                raise RunnerError("Configuration file does not exist: {}".format(config))
            command.append("--input")
            command.append(os.path.abspath(config))

        if data is not None:
            if not os.path.isfile(data):
                raise RunnerError("Data file does not exist: {}".format(data))
            command.append("--data")
            command.append(os.path.abspath(data))

        if output_rank is not None:
            command.append("--output-rank")
            command.append(output_rank)

        super().__init__(command)


