from ...Machine.MachineInterface import MachineInterface
from ...Logging.Logger import log, Severity
from ...UserInterface.UI import UI

class PlaybookStepFailedException(Exception):
    pass

class PlaybookCredentialCollection:
    def __init__(self):
        self.ldapsuche: str | None = None
        self.fwradius: str | None = None
        self.domadmin: str | None = None
        self.root: str | None = None
        self.mli: str | None = None
        self.mli_password : str | None = None
        self.ldap_admin: str | None = None
        self.no_reboot: bool = False

class FileCleanupTask:
    def __init__(self, machine: MachineInterface, file_path: str):
        self.machine = machine
        self.file_path = file_path

    def perform(self) -> bool:
        try:
            self.machine.delete(self.file_path)
            return True
        except Exception as e:
            log(f"Failed to delete file {self.file_path}: {e}", Severity.ERROR)
            return False

class Playbook:
    def __init__(self, ui: UI, is_sub_playbook=False, credentials=None, file_cleanup_stack: None|list[FileCleanupTask]=None):
        self.is_sub_playbook = is_sub_playbook
        self.ui = ui
        self.credentials = PlaybookCredentialCollection() if credentials is None else credentials
        self.file_cleanup_stack: list[FileCleanupTask] = list[FileCleanupTask]() if file_cleanup_stack is None else file_cleanup_stack

    def start(self):
        pass

    def run_steps(self, *steps):
        for step in steps:
            if not step.run(self.file_cleanup_stack, self.credentials):
                log(f"Failed at step {type(step).__name__}", Severity.ERROR)
                raise PlaybookStepFailedException()

    def run_sub_playbook(self, *playbooks: type):
        for playbook_type in playbooks:
            playbook = playbook_type(self.ui, is_sub_playbook=True, credentials=self.credentials, file_cleanup_stack=self.file_cleanup_stack)
            playbook.start()

    def perform_file_cleanup(self):
        for task in self.file_cleanup_stack:
            task.perform()