"""Various entities which describe interface of runner object"""

from parallels.core.utils.entity import Entity


class ExecutionOptions(Entity):
    def __init__(
        self, stdin_content=None, environment_variables=None, working_dir=None, redirect_output_file=None,
        controlled_interruption=None, umask=None, ignore_exit_code=False, log_execution=True, log_output=True,
        output_encoding=None
    ):
        self._stdin_content = stdin_content
        self._environment_variables = environment_variables
        self._working_dir = working_dir
        self._redirect_output_file = redirect_output_file
        self._controlled_interruption = controlled_interruption
        self._umask = umask

        self._ignore_exit_code = ignore_exit_code
        self._log_execution = log_execution
        self._log_output = log_output
        self._output_encoding = output_encoding

    @property
    def ignore_exit_code(self):
        """
        :rtype: bool 
        """
        return self._ignore_exit_code

    @property
    def working_dir(self):
        """
        :rtype: str | None
        """
        return self._working_dir

    @property
    def redirect_output_file(self):
        """
        :rtype: str | None 
        """
        return self._redirect_output_file

    @property
    def stdin_content(self):
        """
        :rtype: str | None 
        """
        return self._stdin_content

    @property
    def environment_variables(self):
        """
        :rtype: dict[str, str] | None 
        """
        return self._environment_variables

    @property
    def log_output(self):
        """
        :rtype: bool 
        """
        return self._log_output

    @property
    def log_execution(self):
        """
        :rtype: bool 
        """
        return self._log_execution

    @property
    def output_encoding(self):
        """Encoding in which the command should emit output to stdout/stderr.

         That property is just a hint for migrator's logging, so we log command's
         output in the most appropriate form. No decoding happens when output is
         returned.

        :rtype: str | None
        """
        return self._output_encoding

    @property
    def controlled_interruption(self):
        """
        :rtype: controlled_interruption: parallels.core.runners.entities.ControlledInterruption | None
        """
        return self._controlled_interruption

    @property
    def umask(self):
        """
        :rtype: int | None 
        """
        return self._umask


class ExecutionResults(Entity):
    def __init__(self, exit_code, stdout, stderr):
        self._exit_code = exit_code
        self._stdout = stdout
        self._stderr = stderr

    @property
    def exit_code(self):
        """
        :rtype: int 
        """
        return self._exit_code

    @property
    def stdout(self):
        """
        :rtype: str 
        """
        return self._stdout

    @property
    def stderr(self):
        """
        :rtype: str 
        """
        return self._stderr


class MSSQLConnectionSettings(Entity):
    """Connection settings to execute queries on MSSQL servers"""
    def __init__(self, host, user, password, database=None):
        self._host = host
        self._user = user
        self._password = password
        self._database = database

    @classmethod
    def create_from_server(cls, database_server):
        """Create entity for specified database server

        :type database_server: parallels.core.connections.database_servers.base.DatabaseServer
        :rtype parallels.core.runners.entities.MSSQLConnectionSettings:
        """
        return cls(host=database_server.host(), user=database_server.user(), password=database_server.password())

    @property
    def host(self):
        """Host name (or IP address) of database server, with instance name

        :rtype: str | unicode
        """
        return self._host

    @property
    def user(self):
        """User login

        :rtype: str | unicode
        """
        return self._user

    @property
    def password(self):
        """Password of user

        :rtype: str | unicode
        """
        return self._password

    @property
    def database(self):
        return self._database


class ControlledInterruption(object):
    def __init__(self, stop_mark, poll_interval=1):
        """
        :type stop_mark: parallels.core.utils.stop_mark.StopMark
        :type poll_interval: int
        """
        self._stop_mark = stop_mark
        self._poll_interval = poll_interval

    @property
    def stop_mark(self):
        """
        :rtype: parallels.core.utils.stop_mark.StopMark 
        """
        return self._stop_mark

    @property
    def poll_interval(self):
        """
        :rtype: int 
        """
        return self._poll_interval


class FileListItem(Entity):
    def __init__(self, name, is_dir):
        self._name = name
        self._is_dir = is_dir

    @property
    def name(self):
        return self._name

    @property
    def is_dir(self):
        return self._is_dir
