#!/usr/bin/env python3
# cleanup-apt-archive
# Python 3.6 compatible

from __future__ import print_function
import os
import sys
import glob
import stat
import time
import shutil
import argparse
import signal

def setup_sigint():
    def handler(signum, frame):
        print("[cleanup-apt-archive] Interrupted.", file=sys.stderr)
        sys.exit(130)  # 128 + SIGINT
    try:
        signal.signal(signal.SIGINT, handler)
    except Exception:
        pass

def list_targets(cache_dir, pattern, recursive):
    if recursive:
        out = []
        for root, dirs, files in os.walk(cache_dir):
            for name in files:
                if name.endswith(pattern.lstrip("*")):  # "*.deb" -> ".deb"
                    out.append(os.path.join(root, name))
        return out
    else:
        return glob.glob(os.path.join(cache_dir, pattern))

def ensure_writable(path):
    try:
        os.chmod(path, stat.S_IWUSR | stat.S_IRUSR)
    except Exception:
        pass

def main():
    parser = argparse.ArgumentParser(description="Delete .deb files from apt cache; quarantine failures to /tmp.")
    parser.add_argument("--dir", default="/var/cache/apt/archives", help="Cache directory (default: %(default)s)")
    parser.add_argument("--pattern", default="*.deb", help="Filename pattern (default: %(default)s)")
    parser.add_argument("--quarantine-parent", default="/tmp", help="Quarantine parent dir (default: %(default)s)")
    parser.add_argument("--recursive", action="store_true", help="Recurse under --dir (off by default)")
    parser.add_argument("--dry-run", action="store_true", help="Show actions without changing anything")
    parser.add_argument("--quiet", action="store_true", help="Minimal output")
    args = parser.parse_args()

    setup_sigint()

    cache_dir = args.dir
    if not os.path.isdir(cache_dir):
        print("[cleanup-apt-archive] Directory not found: {}".format(cache_dir), file=sys.stderr)
        return 1

    targets = list_targets(cache_dir, args.pattern, args.recursive)

    if not targets:
        if not args.quiet:
            print("[cleanup-apt-archive] No matching files in {}".format(cache_dir))
        return 0

    if not args.quiet:
        print("[cleanup-apt-archive] Found {} file(s)".format(len(targets)))

    quarantine_dir = None
    deleted = 0
    quarantined = 0
    failed = 0

    for path in targets:
        try:
            if not (os.path.isfile(path) or os.path.islink(path)):
                continue
        except Exception:
            # If we can't stat, still attempt to move later
            pass

        # Try delete
        try:
            if not args.dry_run:
                ensure_writable(path)
                os.remove(path)
            deleted += 1
            if not args.quiet:
                print("[cleanup-apt-archive] Deleted: {}".format(path))
            continue
        except Exception as e_del:
            if not args.quiet:
                print("[cleanup-apt-archive] Delete failed for {}: {} -> will quarantine".format(path, e_del), file=sys.stderr)

        # Quarantine on failure
        try:
            if quarantine_dir is None:
                ts = time.strftime("%Y%m%d-%H%M%S")
                quarantine_dir = os.path.join(args.quarantine_parent, "deb_quarantine-{}".format(ts))
                if not args.dry_run:
                    os.makedirs(quarantine_dir, exist_ok=True)
            dst = os.path.join(quarantine_dir, os.path.basename(path))
            if not args.dry_run:
                shutil.move(path, dst)
            quarantined += 1
            if not args.quiet:
                print("[cleanup-apt-archive] Quarantined: {} -> {}".format(path, dst))
        except Exception as e_mv:
            failed += 1
            print("[cleanup-apt-archive] Quarantine failed for {}: {}".format(path, e_mv), file=sys.stderr)

    if not args.quiet:
        print("[cleanup-apt-archive] Summary: deleted={}, quarantined={}, failed={}".format(deleted, quarantined, failed))

    return 0 if failed == 0 else 1

if __name__ == "__main__":
    sys.exit(main())
