#!/usr/bin/python3
# autopkgtest-build-lxd is part of autopkgtest
# autopkgtest is a tool for testing Debian binary packages
#
# Copyright © 2006-2015 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-lxd")

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, check_dependencies


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

    parser.add_argument(
        "--vm",
        action="store_true",
        default=False,
        help="Use a virtual machine",
    )
    parser.add_argument(
        "--lxd",
        action="store_const",
        dest="command",
        const="lxd",
        default="",
        help="Use lxd (default if run as autopkgtest-build-lxd)",
    )
    parser.add_argument(
        "--incus",
        action="store_const",
        dest="command",
        const="incus",
        help="Use incus (default if run as autopkgtest-build-incus)",
    )
    parser.add_argument(
        "--remote",
        "-r",
        help="Run container or VM on this remote host instead of locally",
    )
    parser.add_argument(
        "image",
        metavar="IMAGE",
        help="Image to use, e.g. images:debian/trixie/amd64",
    )
    args = parser.parse_args()

    if not args.command:
        tail = os.path.basename(sys.argv[0])

        if "lxd" in tail and "incus" not in tail:
            args.command = "lxd"
        elif "incus" in tail:
            args.command = "incus"
        else:
            parser.error(
                "Must be invoked as autopkgtest-build-lxd or "
                "autopkgtest-build-incus, or with --lxd or --incus "
                "option"
            )

    # 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] = []

    if args.command == "lxd":
        deps.append(Executable("lxc", "lxd or lxd-installer"))
    elif args.command == "incus":
        deps.append(Executable("incus", "incus"))

    deps.extend(
        [
            Executable("dnsmasq", "dnsmasq-base"),
            Executable("ip", "iproute2"),
        ]
    )

    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-lxd.sh")
        argv = [str(script), f"--{args.command}"]

        if args.vm:
            argv.append("--vm")

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

        argv.append(args.image)
        subprocess.run(argv, check=True)

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