from ..Playbooks.Playbook import FileCleanupTask, PlaybookCredentialCollection
from ...Logging.Logger import log, Severity
from ...Machine.MachineInterface import MachineInterface
from ..SetupStep import SetupStep

from hashlib import sha512
from secrets import choice

import string

class SetPamPassword(SetupStep):
    def __init__(self, target_machine: MachineInterface, username: str, password: str, method: str):
        super().__init__()
        self.target_machine = target_machine
        self.username = username
        self.password = password
        self.method = method

    def get_crypt(self) -> str|None:
        stdin, stdout, stderr = self.target_machine.execute_shell_command_live("mkpasswd","--stdin", "-m", self.method)
        stdin.write(self.password.encode())
        stdin.write('\n'.encode())
        stdin.flush()

        if stderr.readable():
            error = stderr.read().strip().decode()
            if len(error) > 0:
                log(error, Severity.ERROR)
                return None

        hash = stdout.readline()
        if isinstance(hash, bytes):
            hash = hash.decode()
        return hash.strip()


    def run(self, file_cleanup_stack : list[FileCleanupTask], credentials: PlaybookCredentialCollection) -> bool:
        crypt_hash = self.get_crypt()
        if crypt_hash is None:
            log("Unable to calculate hash.", Severity.ERROR)
            return False

        log(f"Crypt hash is {crypt_hash}", Severity.TRACE)
        stdout, stderr, retval = self.target_machine.execute_shell_command("usermod", "--password", crypt_hash, self.username)

        if retval != 0:
            log(stderr, Severity.ERROR)
            return False
        log(f"Password for {self.username}@{self.target_machine.get_hostname()}")
        return True
