#!/usr/bin/env python3
# SPDX-License-Identifier: BSD-3-Clause
# Author: Christian Kastner <ckk@kvr.at>


import argparse
import os
import platform
import psutil
import sys


SUPPORTED_ARCHS = {
    'x86_64': 'amd64',
    'i386': 'i386'
}


MACHINE = platform.machine()
try:
    ARCH = SUPPORTED_ARCHS[MACHINE]
except KeyError as e:
    print(f"Unsupported machine type {MACHINE}", file=sys.stderr)
    sys.exit(1)
# Defaults
MEM = 2048
CPUS = psutil.cpu_count(logical=False)
DIST = 'unstable'
IMAGEDIR = os.environ.get('IMAGEDIR', '/var/cache/qemu-sbuild')


def main():
    # init options
    parser = argparse.ArgumentParser(
        description="Build Debian packages using sbuild(1) and QEMU images",
        epilog="All other options are passed on through to sbuild(1). "
               "The image will be started in -snapshot mode, so no changes "
               "are saved, and multiple processes can use the same image "
               "concurrently.",
    )
    parser.add_argument(
        '--arch',
        action='store',
        default=ARCH,
        help="Architecture to use. Default is the host architecture. "
             "Currently supported architectures are: "
            f"{', '.join(SUPPORTED_ARCHS.values())}.",
    )
    parser.add_argument(
        '-d', '--dist',
        action='store',
        default=DIST,
        help=f"Distribution (for the .changes file). Default is '{DIST}'.",
    )
    parser.add_argument(
        '--image',
        action='store',
        help="VM image to use for building. If not specified, will look in "
             "$IMAGEDIR for an image with the name DIST-autopkgtest-ARCH.img. "
             "A suitable image can be created with qemu-sbuild-create(1).",
    )
    parser.add_argument(
        '--autopkgtest-debug',
        action='store_true',
        help="Enable debug output for the autopkgtest-virt-qemu(1) driver.",
    )
    parser.add_argument(
        '--ram',
        metavar='MiB',
        action='store',
        default=MEM,
        help=f"VM memory size in MB. Default: {MEM}",
    )
    parser.add_argument(
        '--cpus',
        metavar='CPUs',
        action='store',
        default=CPUS,
        help="VM CPU count. Default: Number of physical cores on the host.",
    )
    parser.add_argument(
        '--overlay-dir',
        action='store',
        help="Directory for the temporary image overlay instead of "
             "autopkgtest's default of /tmp (or $TMPDIR).",
    )
    parser.add_argument(
        '--noexec',
        action='store_true',
        help="Don't actually do anything. Just print the sbuild(1) command "
             "string that would be executed, and then exit.",
    )
    parsed_args, unparsed_args = parser.parse_known_args()

    if parsed_args.image:
        image = parsed_args.image
    else:
        image = os.path.join(
            IMAGEDIR,
            f'{parsed_args.dist}-autopkgtest-{ARCH}.img'
        )
    qemu = f'qemu-system-{MACHINE}'

    args = [
            'sbuild',
            '--arch',                           parsed_args.arch,
            '--dist',                           parsed_args.dist,
            '--purge-build=never',
            '--purge-deps=never',
            '--chroot-mode=autopkgtest',
            '--autopkgtest-virt-server=qemu',
            '--autopkgtest-virt-server-opt',    '--overlay-dir=/tmp',
            '--autopkgtest-virt-server-opt',    f'--qemu-command={qemu}',
            '--autopkgtest-virt-server-opt',    f'--ram-size={parsed_args.ram}',
            '--autopkgtest-virt-server-opt',    f'--cpus={parsed_args.cpus}',
            '--autopkgtest-virt-server-opt',    image,
            # Worarkound -- dose can hang stuff in a qemu VM
            '--bd-uninstallable-explainer',     'apt',
        ]
    if parsed_args.autopkgtest_debug:
        args += ['--autopkgtest-virt-server-opt', '--debug']
    if parsed_args.overlay_dir:
        d = parsed_args.overlay_dir
        args += ['--autopkgtest-virt-server-opt', f'--overlay_dir={d}']

    # Pass on the remaining arguments to sbuild
    args += unparsed_args

    print(' '.join(str(a) for a in args))
    if not parsed_args.noexec:
        os.execvp(args[0], args)


if __name__ == '__main__':
    main()
