#!/usr/bin/python3
#
# SPDX-License-Identifier: GPL-2.0-only
# (c) 2026 Gerd Hoffmann
#
# pylint: disable=too-many-arguments
# pylint: disable=too-many-positional-arguments
""" generate cloud init iso images """
import pathlib
import tempfile
import subprocess

import yaml

from passlib.hash import sha512_crypt

class CloudInitISO:
    """ cloud init iso image generator """

    def __init__(self, hostname):
        self.config = {
            "hostname": hostname,
            "users": [],
            "packages": [],
            "runcmd": [],
            "bootcmd": [],
        }
        self.meta = {
            "local-hostname": hostname
        }

    def add_user(self, name, passwd = None, ssh_keys = None, sudo = False, shell = "/bin/bash"):
        user = {
            "name"  : name,
            "shell" : shell
        }
        if passwd:
            cpasswd = sha512_crypt.hash(passwd)
            user["passwd"] = cpasswd
            user["lock_passwd"] = False
        if ssh_keys:
            user["ssh_authorized_keys"] = ssh_keys
        if sudo:
            user["sudo"] = ["ALL=(ALL) NOPASSWD:ALL"]
        self.config["users"].append(user)

    def add_package(self, package_name):
        self.config["packages"].append(package_name)

    def add_runcmd(self, command):
        """ command to run on first boot """
        self.config["runcmd"].append(command)

    def add_bootcmd(self, command):
        """ command to run on every boot """
        self.config["bootcmd"].append(command)

    # pylint: disable=consider-using-with
    def create_iso(self):
        iso = tempfile.NamedTemporaryFile(suffix = '.iso')
        with tempfile.TemporaryDirectory() as tmpdir:
            tmpdir = pathlib.Path(tmpdir)

            user_data_file = tmpdir / "user-data"
            with user_data_file.open("w") as f:
                f.write("#cloud-config\n")
                yaml.safe_dump(self.config, f, default_flow_style=False)

            meta_data_file = tmpdir / "meta-data"
            with meta_data_file.open("w") as f:
                yaml.safe_dump(self.meta, f, default_flow_style=False)

            subprocess.run([
                "xorrisofs",
                "-output", iso.name,
                "-volid", "cidata",
                "-joliet",
                "-rock",
                str(user_data_file),
                str(meta_data_file)
            ], capture_output = True, check=True)

        return iso
