from ...Logging.Logger import log, Severity
from ...Machine.PaedMLMachineCollection import MACHINE_COLLECTION
from ...SetupSteps.Playbooks.Playbook import FileCleanupTask, PlaybookCredentialCollection
from ...SetupSteps.SetupStep import SetupStep


class ApplyCertificatesToOpsi(SetupStep):
    def run(self, file_cleanup_stack: list[FileCleanupTask], credentials: PlaybookCredentialCollection) -> bool:
        log('Applying certificates to OPSI...')
        backup = MACHINE_COLLECTION.backup
        backup.delete('/etc/opsi/opsiconfd.pem.orig')
        backup.move('/etc/opsi/opsiconfd.pem', '/etc/opsi/opsiconfd.pem.orig')

        stdout, stderr, retval = backup.execute_shell_command('openssl', 'x509',
                                                              '-outform', 'pem',
                                                              '-in', f'/etc/univention/ssl/{backup.get_hostname()}/cert.pem',
                                                              '-out', '/etc/opsi/opsiconfd.pem')
        if retval != 0:
            log(f'Failed to apply certificate: {stderr}', Severity.ERROR)
            return False

        pem = backup.read_file('/etc/opsi/opsiconfd.pem')
        pk = backup.read_file(f'/etc/univention/ssl/{backup.get_hostname()}/private.key')

        combined = pem + pk

        backup.write_file('/etc/opsi/opsiconfd.pem', combined)

        stdout, stderr, retval = backup.execute_shell_command('chown', 'opsiconfd:opsiadmin', '/etc/opsi/opsiconfd.pem')
        if retval != 0:
            log(f'Failed to change ownership of certificate file: {stderr}', Severity.ERROR)
            return False

        stdout, stderr, retval = backup.execute_shell_command('chmod', '400', '/etc/opsi/opsiconfd.pem')
        if retval != 0:
            log(f'Failed to change permissions of certificate file: {stderr}', Severity.ERROR)
            return False

        stdout, stderr, retval = backup.execute_shell_command('systemctl', 'restart', 'opsiconfd.service')
        if retval != 0:
            log(f'Failed to restart opsiconfd: {stderr}', Severity.ERROR)
            return False

        log('Certificates have been applied.', Severity.DEBUG)
        return True