#!/usr/bin/env python3
"""Cancel all CUPS print jobs older than a specified number of days."""

import subprocess
import sys
from datetime import datetime, timedelta

DAYS = 7
DRY_RUN = False
for arg in sys.argv[1:]:
    if arg == "--dry-run":
        DRY_RUN = True
    else:
        try:
            DAYS = int(arg)
        except ValueError:
            print(f"Unknown argument: {arg}", file=sys.stderr)
            sys.exit(1)
cutoff = datetime.now() - timedelta(days=DAYS)

print(f"Cancelling jobs older than {DAYS} days (before {cutoff.strftime('%Y-%m-%d %H:%M')})")
if DRY_RUN:
    print("** DRY RUN - no jobs will actually be cancelled **")
print()

# lpstat -W not-completed -o gives one line per queued job:
#   HOPP01-129732         unknown         8963072   Sat 21 Mar 2026 06:41:48 AM CDT
result = subprocess.run(
    ["lpstat", "-W", "not-completed", "-o"],
    capture_output=True, text=True
)

if result.returncode != 0:
    print(f"lpstat error: {result.stderr.strip()}", file=sys.stderr)
    sys.exit(1)

cancelled = 0
skipped = 0
errors = 0

for line in result.stdout.splitlines():
    line = line.strip()
    if not line:
        continue

    parts = line.split()
    if len(parts) < 6:
        continue

    job_id = parts[0]

    # Date string starts after the size field.
    # Format: "DayOfWeek DD Mon YYYY HH:MM:SS AM/PM TZ"
    # Find it by looking for the day-of-week token after the size.
    # parts[0]=job_id, parts[1]=user, parts[2]=size, parts[3:]=date tokens
    date_str = " ".join(parts[3:])

    # Try parsing with and without timezone (some CUPS versions differ)
    job_time = None
    for fmt in (
        "%a %d %b %Y %I:%M:%S %p %Z",
        "%a %d %b %Y %I:%M:%S %p",
    ):
        try:
            job_time = datetime.strptime(date_str, fmt)
            break
        except ValueError:
            continue

    if job_time is None:
        # Try dropping the last token (timezone) manually
        try:
            job_time = datetime.strptime(" ".join(parts[3:-1]), "%a %d %b %Y %I:%M:%S %p")
        except ValueError:
            print(f"  SKIP {job_id} - could not parse date: {date_str}")
            skipped += 1
            continue

    if job_time < cutoff:
        if DRY_RUN:
            print(f"  WOULD CANCEL {job_id}  ({job_time.strftime('%Y-%m-%d %H:%M')})")
            cancelled += 1
        else:
            cp = subprocess.run(["cancel", job_id], capture_output=True, text=True)
            if cp.returncode == 0:
                print(f"  CANCELLED {job_id}  ({job_time.strftime('%Y-%m-%d %H:%M')})")
                cancelled += 1
            else:
                print(f"  ERROR cancelling {job_id}: {cp.stderr.strip()}")
                errors += 1
    else:
        skipped += 1

print(f"\nDone: {cancelled} cancelled, {skipped} skipped (newer), {errors} errors")

