#!/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

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)
