#!/usr/bin/env python3
# SPDX-License-Identifier: GPL-2.0-only
# Copyright (C) 2025-2026 Guillaume Tucker

"""Containerized builds"""

import abc
import argparse
import dataclasses
import logging
import os
import pathlib
import shutil
import subprocess
import sys
import tomllib
import uuid


class ContainerRuntime(abc.ABC):
    """Base class for a container runtime implementation"""

    name = None  # Property defined in each implementation class

    def __init__(self, args, config, logger):
        def _first_not_none(*args):
            return next((item for item in args if item is not None))

        self._uid = _first_not_none(
            args.uid, config.uid, os.getuid()
        )
        self._gid = _first_not_none(
            args.gid, config.gid, args.uid, config.uid, os.getgid()
        )
        self._env_file = args.env_file or config.env_file
        self._shell = args.shell
        self._logger = logger

    @classmethod
    def is_present(cls):
        """Determine whether the runtime is present on the system"""
        return shutil.which(cls.name) is not None

    @abc.abstractmethod
    def _do_run(self, image, cmd, container_name):
        """Runtime-specific handler to run a command in a container"""

    @abc.abstractmethod
    def _do_abort(self, container_name):
        """Runtime-specific handler to abort a running container"""

    def run(self, image, cmd):
        """Run a command in a runtime container"""
        container_name = str(uuid.uuid4())
        self._logger.debug("container: %s", container_name)
        try:
            return self._do_run(image, cmd, container_name)
        except KeyboardInterrupt:
            self._logger.error("user aborted")
            self._do_abort(container_name)
            return 1


class CommonRuntime(ContainerRuntime):
    """Common logic for Docker and Podman"""

    def _do_run(self, image, cmd, container_name):
        cmdline = [self.name, 'run']
        cmdline += self._get_opts(container_name)
        cmdline.append(image)
        cmdline += cmd
        self._logger.debug('command: %s', ' '.join(cmdline))
        return subprocess.call(cmdline)

    def _get_opts(self, container_name):
        opts = [
            '--name', container_name,
            '--rm',
            '--volume', f'{pathlib.Path.cwd()}:/src',
            '--workdir', '/src',
        ]
        if self._env_file:
            opts += ['--env-file', self._env_file]
        if self._shell:
            opts += ['--interactive', '--tty']
        return opts

    def _do_abort(self, container_name):
        subprocess.call([self.name, 'kill', container_name])


class DockerRuntime(CommonRuntime):
    """Run a command in a Docker container"""

    name = 'docker'

    def _get_opts(self, container_name):
        return super()._get_opts(container_name) + [
            '--user', f'{self._uid}:{self._gid}'
        ]


class PodmanRuntime(CommonRuntime):
    """Run a command in a Podman container"""

    name = 'podman'

    def _get_opts(self, container_name):
        return super()._get_opts(container_name) + [
            '--userns', f'keep-id:uid={self._uid},gid={self._gid}',
        ]


class Runtimes:
    """List of all supported runtimes"""

    runtimes = [PodmanRuntime, DockerRuntime]

    @classmethod
    def get_names(cls):
        """Get a list of all the runtime names"""
        return list(runtime.name for runtime in cls.runtimes)

    @classmethod
    def get(cls, name):
        """Get a single runtime class matching the given name"""
        for runtime in cls.runtimes:
            if runtime.name == name:
                if not runtime.is_present():
                    raise ValueError(f"runtime not found: {name}")
                return runtime
        raise ValueError(f"unknown runtime: {name}")

    @classmethod
    def find(cls):
        """Find the first runtime present on the system"""
        for runtime in cls.runtimes:
            if runtime.is_present():
                return runtime
        raise ValueError("no runtime found")


@dataclasses.dataclass
class Config:
    """Container configuration"""
    image: str = None
    runtime: str = None
    env_file: str = None
    uid: int = None
    gid: int = None

    @classmethod
    def from_toml(cls, config_file_path, profile_name):
        """Create a config object from a TOML file"""
        if not config_file_path:
            config_file_path = '.container.toml'
            if not os.path.exists(config_file_path):
                return cls()
        elif not os.path.exists(config_file_path):
            raise ValueError(f"config file not found: {config_file_path}")
        with open(config_file_path, 'rb') as config_file:
            config = tomllib.load(config_file)
        default = config.get('DEFAULT', {})
        if not profile_name:
            profile = {}
        else:
            profile = config.get(profile_name)
            if profile is None:
                raise ValueError(f"unknown profile: {profile_name}")
        kwargs = {
            name: type(value) for (name, type, value) in (
                (op.name, op.type, profile.get(op.name, default.get(op.name)))
                for op in dataclasses.fields(cls)
            ) if value is not None
        }
        return cls(**kwargs)


def _get_logger(verbose):
    """Set up a logger with the appropriate level"""
    logger = logging.getLogger('container')
    handler = logging.StreamHandler()
    handler.setFormatter(logging.Formatter(
        fmt='[container {levelname}] {message}', style='{'
    ))
    logger.addHandler(handler)
    logger.setLevel(logging.DEBUG if verbose is True else logging.INFO)
    return logger


def main(args):
    """Main entry point for the container tool"""
    logger = _get_logger(args.verbose)
    try:
        config = Config.from_toml(args.config_file, args.config_profile)
        runtime = args.runtime or config.runtime
        cls = Runtimes.get(runtime) if runtime else Runtimes.find()
    except ValueError as ex:
        logger.error(ex)
        return 1
    logger.debug("runtime: %s", cls.name)
    image = args.image or config.image
    if not image:
        logger.error("no image specified")
        return 1
    logger.debug("image: %s", image)
    return cls(args, config, logger).run(image, args.cmd)


if __name__ == '__main__':
    parser = argparse.ArgumentParser(
        'container',
        description="See the documentation for more details: "
        "https://docs.kernel.org/dev-tools/container.html"
    )
    parser.add_argument(
        '-c', '--config-file',
        help="Path to the config file.  If not specified, the default is to "
        "look for .container.toml in the current working directory."
    )
    parser.add_argument(
        '-e', '--env-file',
        help="Path to an environment file to load in the container."
    )
    parser.add_argument(
        '-g', '--gid', type=int,
        help="Group ID to use inside the container."
    )
    parser.add_argument(
        '-i', '--image',
        help="Container image name."
    )
    parser.add_argument(
        '-p', '--config-profile',
        help="Profile section to use in the config file.  This will override "
        "any values defined in the DEFAULT section."
    )
    parser.add_argument(
        '-r', '--runtime', choices=Runtimes.get_names(),
        help="Container runtime name.  If not specified, the first one found "
        "on the system will be used i.e. Podman if present, otherwise Docker."
    )
    parser.add_argument(
        '-s', '--shell', action='store_true',
        help="Run the container in an interactive shell."
    )
    parser.add_argument(
        '-u', '--uid', type=int,
        help="User ID to use inside the container.  If the -g option is not "
        "specified and no group ID is defined in the configuration file, the "
        "user ID will also be set as the group ID."
    )
    parser.add_argument(
        '-v', '--verbose', action='store_true',
        help="Enable verbose output."
    )
    parser.add_argument(
        'cmd', nargs='+',
        help="Command to run in the container"
    )
    sys.exit(main(parser.parse_args(sys.argv[1:])))
