from yta_validation.parameter import ParameterValidator
from yta_programming.singleton import SingletonMeta
from typing import Union


"""
TODO: Maybe we can turn the current boolean flag into
a mode that can control the way we print and log the
information into the files (when this functionality
is implemented).
"""
class ConsolePrinter(metaclass = SingletonMeta):
    """
    *Singleton class*

    Class to wrap functionality related to printing
    messages in the console.

    This is useful when we want to control the messages
    we print with a single parameter, that can be a
    general setting that we pass to this singleton
    instance to control it and avoid printing if the
    print mode is not activated.
    """

    def __init__(
        self,
        do_print: bool = True
    ):
        self._do_print: bool = do_print
        """
        *For internal use only*

        Flag to indicate if we need to print the messages when
        any `.print()` method is called in this instance.
        """

    def activate_print(
        self
    ) -> 'ConsolePrinter':
        """
        Activate the printing mode, which means that when any
        `.print()` method is called, it will actually print
        the expected message.
        """
        self._do_print = True

    def deactivate_print(
        self
    ) -> 'ConsolePrinter':
        """
        Deactivate the printing mode, which means that when
        any `.print()` method is called, it will actually print
        not the expected message.
        """
        self._do_print = False

    def _print(
        self,
        message: Union[str, any] = ''
    ) -> 'ConsolePrinter':
        """
        *For internal use only*

        Internal method to simplify the way we print the message
        (or not) according to the internal flag.

        This method should be called by the other printing methods.
        """
        if self._do_print:
            print(message)

        return self

    def print(
        self,
        message: Union[str, any] = ''
    ) -> 'ConsolePrinter':
        """
        Print the `message` provided only if the internal flag
        that allows printing (or not) is activated.
        """
        return self._print(message)
    
    def print_error(
        self,
        message: str = ''
    ) -> 'ConsolePrinter':
        """
        Print the `message` provided as an error if the internal
        flag (to print) is activated.
        """
        ParameterValidator.validate_string('message', message, do_accept_empty = True)

        return self._print(f'>>>> [ERROR] <<<< {message}')
    
    def print_in_progress(
        self,
        message: str = ''
    ) -> 'ConsolePrinter':
        """
        Print the `message` provided as an error if the internal
        flag (to print) is activated.
        """
        ParameterValidator.validate_string('message', message, do_accept_empty = True)

        return self._print(f'.... {message}')
    
    def print_completed(
        self,
        message: str = ''
    ) -> 'ConsolePrinter':
        """
        Print the `message` provided as an error if the internal
        flag (to print) is activated.
        """
        ParameterValidator.validate_string('message', message, do_accept_empty = True)

        return self._print(f'[OK] {message}')