#!/usr/bin/env python3
#
# Tool to detect reverse-dependency on a package that don't define autopkgtests
# The output is a pair of file, to feed to mass-bug for bug reporting
#
# Copyright (c) 2023 Sandro Tosi <morph@debian.org>
# License: MIT

import argparse
import pathlib
import subprocess
import sys

import debian.deb822 as d822
from rich.console import Console
from rich.progress import track

console = Console()

parser = argparse.ArgumentParser()
parser.add_argument('--package', default=None)
parser.add_argument('--bts-user', default=None)
parser.add_argument('--bts-tag', default=None)
parser.add_argument('--debemail', default="YOUR NAME <email@domain.ext>")

args = parser.parse_args()
if args.package is None:
    console.print("[red]ERROR: please specify the package to check\n")
    parser.print_help(sys.stderr)
    sys.exit(1)
if args.bts_user is None:
    console.print("[red]ERROR: please specify the BTS username to use\n")
    parser.print_help(sys.stderr)
    sys.exit(1)
if args.bts_tag is None:
    args.bts_tag = f'missing-adt-{args.package}'

MASSBUG_BODY = f"""Dear maintainer,
#PACKAGE# has a package relationship with {args.package} (either a
Depends/Recommends/Suggests or a build-time dependency) but doesn't defineany
autopkgtests.

Autopkgtests allow for automation to verify reverse-dependencies are still
working and/or building properly after a package is uploaded, and are helpful
in preventing a package from migrating to testing if they break other packages.

For these reasons, please add "meaningful" autopkgtests to this package, which
usually means running the upstream unittests.

Further information can be found at:

 * https://manpages.debian.org/unstable/autopkgtest/autopkgtest.1.en.html
 * https://manpages.debian.org/unstable/dh-python/pybuild-autopkgtest.1.en.html


Thanks!

Package list generated by:

  https://github.com/sandrotosi/debian-tools/blob/master/find_rdeps_without_autopkgtests.py
"""

# it's quite hard to find all the source and binary packages having a relationship with PKG, so take the `apt-rdepends` approximation here
rdeps = subprocess.run(['apt-rdepends', '-r', '--follow=Obsoletes', args.package], stdout=subprocess.PIPE, stderr=subprocess.PIPE).stdout.decode()
rdeps = [x.split()[2] for x in rdeps.splitlines() if x.startswith('  Reverse Depends')]

ok, ko = set(), set()

for rdep in track(rdeps, description="Processing rdeps..."):
    aptcache = subprocess.run(['apt-cache', 'showsrc', rdep], stdout=subprocess.PIPE, stderr=subprocess.PIPE).stdout.decode()
    data = d822.Deb822(aptcache)
    if 'Testsuite' in data:
        ok.add(data['Package'])
    else:
        ko.add(data['Package'])

console.print("Summary:")
console.print(f"  Total rdeps processed:            {len(rdeps)}")
console.print(f"  Total rdeps with    autopkgtests: [green]{len(ok)}")
console.print(f"  Total rdeps [underline]without[/underline] autopkgtests: [red]{len(ko)}")


console.print("rdeps with autopkgtests")
for pkg in sorted(ok):
    console.print(f"  {pkg}", style="green")
console.print("rdeps WITHOUT autopkgtests")
for pkg in sorted(ko):
    console.print(f"  {pkg}", style="red")

pkgs_filename = f'{args.package}_pkgs'
body_filename = f'{args.package}_body'

pathlib.Path(pkgs_filename).open('w').write('\n'.join(sorted(ko)))
pathlib.Path(body_filename).open('w').write(MASSBUG_BODY)

console.print("\nA set of 2 files have been generated in the current directory:")
console.print(f"  - the bug report template body: {body_filename}")
console.print(f"  - the packages list: {pkgs_filename}\n")

console.print("You can now run `mass-bug` to file the bug reports:\n")
print(f'    DEBEMAIL="{args.debemail}" mass-bug --subject="please add autopkgtests (to add coverage for {args.package})" --user={args.bts_user} --usertags={args.bts_tag} --source --no-wrap --severity=normal {body_filename} {pkgs_filename}')
console.print("\nNOTE: to actually submit the reports, append `--send` to the command above")
