#!/usr/bin/python3
# autopkgtest-build-lxc is part of autopkgtest
# autopkgtest is a tool for testing Debian binary packages
#
# Copyright © 2006-2014 Canonical Ltd.
# Copyright © 2024 Simon McVittie
# SPDX-License-Identifier: GPL-2.0-or-later

# ruff: noqa: E402

import argparse
import logging
import os
import subprocess
import sys
from pathlib import Path
from typing import Any, List


logger = logging.getLogger("autopkgtest-build-lxc")

DATA_PATHS = (
    os.path.dirname(os.path.dirname(os.path.abspath(__file__))),
    "/usr/share/autopkgtest",
)

for p in reversed(DATA_PATHS):
    sys.path.insert(0, os.path.join(p, "lib"))

from adt_testbed import PKGDATADIR
from autopkgtest_deps import (
    Dependency,
    Executable,
    FileDependency,
    check_dependencies,
)


def parse_args() -> Any:
    parser = argparse.ArgumentParser(fromfile_prefix_chars="@")

    parser.add_argument(
        "--architecture",
        "--arch",
        default="",
        help="dpkg architecture name",
    )
    parser.add_argument(
        "--keyring",
        default="",
        help="Path to trusted apt keyring",
    )
    parser.add_argument(
        "--script",
        default="",
        help="Script to run inside the container",
    )
    parser.add_argument(
        "distro",
        metavar="debian|ubuntu|kali",
        help="Distribution vendor",
    )
    parser.add_argument(
        "release",
        metavar="RELEASE",
        help="Distribution release suite",
    )
    parser.add_argument(
        "_architecture",
        default=None,
        metavar="ARCHITECTURE",
        nargs="?",
        help="Deprecated, use --architecture instead",
    )
    parser.add_argument(
        "_script",
        default=None,
        metavar="SCRIPT",
        nargs="?",
        help="Deprecated, use --script instead",
    )
    args = parser.parse_args()

    if args._architecture is not None:
        if args.architecture:
            parser.error(
                "--architecture and 3rd positional argument cannot both be specified"
            )
        else:
            args.architecture = args._architecture

    if args._script is not None:
        if args.script:
            parser.error(
                "--script and 4th positional argument cannot both be specified"
            )
        else:
            args.script = args._script

    # Some required tools are in /usr/sbin
    path = os.environ["PATH"]

    if "/usr/sbin" not in path.split(":"):
        os.environ["PATH"] = path + ":/usr/sbin:/sbin"

    deps: List[Dependency] = [
        Executable("debootstrap", "debootstrap"),
        Executable("lxc-config", "lxc"),
        Executable("ip", "iproute2"),
        Executable("rsync", "rsync"),
        Executable("newuidmap", "uidmap"),
        FileDependency(
            Path(f"/usr/share/lxc/templates/lxc-{args.distro}"),
            "lxc-templates",
        ),
    ]

    if not check_dependencies(deps):
        sys.exit(2)

    return args


if __name__ == "__main__":
    logging.basicConfig()
    logging.getLogger().setLevel(logging.INFO)

    try:
        args = parse_args()

        # TODO: Move the functionality of the shell script into Python
        script = Path(PKGDATADIR, "lib", "build-lxc.sh")
        argv = [str(script)]

        if args.keyring:
            argv.append(f"--keyring={args.keyring}")

        argv.extend(
            [
                args.distro,
                args.release,
                args.architecture,
                args.script,
            ]
        )
        subprocess.run(argv, check=True)

    except subprocess.CalledProcessError as e:
        logger.error("%s", e)
        sys.exit(e.returncode or 1)
