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

"""Containerized builds"""

import abc
import argparse
import logging
import os
import pathlib
import shutil
import subprocess
import sys
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, logger):
        self._uid = args.uid or os.getuid()
        self._gid = args.gid or args.uid or os.getgid()
        self._env_file = args.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")


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:
        cls = Runtimes.get(args.runtime) if args.runtime else Runtimes.find()
    except ValueError as ex:
        logger.error(ex)
        return 1
    logger.debug("runtime: %s", cls.name)
    logger.debug("image: %s", args.image)
    return cls(args, logger).run(args.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(
        '-e', '--env-file',
        help="Path to an environment file to load in the container."
    )
    parser.add_argument(
        '-g', '--gid',
        help="Group ID to use inside the container."
    )
    parser.add_argument(
        '-i', '--image', required=True,
        help="Container image name."
    )
    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',
        help="User ID to use inside the container.  If the -g option is not "
        "specified, 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:])))
