# Imports

from .commands import Command

# Exports

__all__ = (
    "Script",
)

# Classes


class Script(object):
    """A collection of commands."""

    def __init__(self, name, shell="/bin/bash"):
        """Initialize the factory.

        :param name: The name of the script.
        :type name: str

        :param shell: The shell command to use.
        :type shell: str

        """
        self.name = name
        self.shell = shell
        self._commands = list()

    def __iter__(self):
        return iter(self._commands)

    def __len__(self):
        return len(self._commands)

    def __repr__(self):
        return "<%s %s>" % (self.__class__.__name__, self.name)

    def __str__(self):
        return self.to_string()

    def add(self, command, **kwargs):
        """Add a command to the script.

        :param command: The command to be added.
        :type command: str | Command

        :raise: TypeError

        kwargs are used to instantiate a new command instance when ``command`` is given as a string.

        """
        if isinstance(command, Command):
            self._commands.append(command)
        elif type(command) is str:
            command = Command(command, **kwargs)
            self._commands.append(command)
        else:
            raise TypeError("The given command must be a str or instance of Command: %s" % type(command))

    def get_commands(self):
        """Get the commands generated by the factory.

        :rtype: list[BaseType[Command]]

        """
        return self._commands

    def to_string(self):
        """Export the script as a string.

        :rtype: str

        """
        a = list()

        if self.shell is not None:
            a.append("#! %s" % self.shell)
            a.append("")

        for c in self._commands:
            if c.comment:
                a.append("# %s" % c.comment)

            a.append(c.preview())
            a.append("")

        return "\n".join(a)
