from typing import Dict, List, Optional


class JobDescription:
    """Describes a job to submit to a scheduler.

    Attributes:
        name (str): The name of the job, with which it will show up in \
                the scheduler's queue. Cerulean does not use the name, \
                but it may be useful if you manually check the queue.
        working_directory (str): The working directory to execute in.
        environment (Dict[str, str]): A dictionary of environment \
                variables to define, and their values.
        command (str): The command to execute.
        arguments (list of str): A list of arguments to pass. If needed, \
                you need to add quotes yourself, the arguments will not \
                be escaped by cerulean.
        stdout_file (str): File to direct standard output to.
        stderr_file (str): File to direct standard error to.
        queue_name (str): Name of the queue to submit to.
        time_reserved (int): Time to reserve, in seconds.
        num_nodes (int): The number of nodes to reserve.
        mpi_processes_per_node (int): Number of MPI processes to start per \
                node.
        system_out_file (str): File to direct the standard output of \
                the scheduler to.
        system_err_file (str): File to direct the standard error of \
                the scheduler to.
        extra_scheduler_options (str): Additional options to add to the \
                scheduler command line on job submission. Note that these \
                are scheduler-specific!

        Note that stdout_file and stderr_file will receive the output \
        of the process you are starting, while system_out_file and \
        system_err_file will receive messages from the scheduler (e.g. \
        that the job ran out of its time limit and was killed). If \
        stdout_file and/or stderr_file are not specified but \
        system_out_file and/or system_err_file are, then the command \
        output/error will end up in the system output/error file \
        together with the scheduler output.

    """

    def __init__(self) -> None:
        """Create a default JobDescription.

        This sets the name of the job to `cerulean` and everything
        else to None or an empty dict or list.
        """
        self.name = 'cerulean'
        self.working_directory = None  # type: Optional[str]
        self.environment = dict()   # type: Dict[str, str]
        self.command = None     # type: Optional[str]
        self.arguments = []     # type: List[str]
        self.stdout_file = None     # type: Optional[str]
        self.stderr_file = None     # type: Optional[str]
        self.queue_name = None  # type: Optional[str]
        self.time_reserved = None   # type: Optional[int]
        self.num_nodes = None   # type: Optional[int]
        self.mpi_processes_per_node = None  # type: Optional[int]
        self.system_out_file = None     # type: Optional[str]
        self.system_err_file = None     # type: Optional[str]
        self.extra_scheduler_options = None  # type: Optional[str]
