"""Delete all rows for a given actor across every Iceberg snapshot.

Right-to-be-forgotten under GDPR Article 17 requires hard-deletion,
not just soft-flag. For Iceberg tables this means:
  1. DELETE matching rows from the current snapshot
  2. expire_snapshots() to physically remove old data files that
     still contained the rows

This script handles both. It is idempotent — re-running it is a no-op.
"""

from __future__ import annotations

import argparse
import sys
from typing import Iterable

try:
    from pyiceberg.catalog import load_catalog
    from pyiceberg.expressions import EqualTo
except ImportError:
    print("right_to_be_forgotten.py requires pyiceberg; "
          "pip install 'pyiceberg[duckdb]'", file=sys.stderr)
    sys.exit(2)

DEFAULT_CATALOG = "gharchive_local"
DEFAULT_TABLES = ("events_raw", "dim_actors", "fact_events")


def delete_actor(actor: str,
                 catalog_name: str = DEFAULT_CATALOG,
                 tables: Iterable[str] = DEFAULT_TABLES) -> dict[str, int]:
    """Delete all rows for a given actor and expire old Iceberg snapshots.

    Args:
        actor:        The actor value to match on the ``actor`` column.
        catalog_name: Name of the Iceberg catalog to load.
        tables:       Iterable of table names to process.

    Returns:
        Dict mapping each table name to the number of rows deleted.
    """
    catalog = load_catalog(catalog_name)
    deleted: dict[str, int] = {}
    for tname in tables:
        tbl = catalog.load_table(tname)
        before = tbl.scan().to_pandas().shape[0]
        tbl.delete(EqualTo("actor", actor))
        after = tbl.scan().to_pandas().shape[0]
        deleted[tname] = before - after
        tbl.expire_snapshots()
    return deleted


def main() -> None:
    p = argparse.ArgumentParser(
        description="GDPR right-to-be-forgotten: hard-delete an actor "
                    "from all Iceberg tables and expire old snapshots."
    )
    p.add_argument("--actor", required=True,
                   help="actor value to delete (e.g. 'target-user')")
    p.add_argument("--catalog", default=DEFAULT_CATALOG,
                   help=f"Iceberg catalog name (default: {DEFAULT_CATALOG})")
    args = p.parse_args()
    result = delete_actor(args.actor, catalog_name=args.catalog)
    for tname, n in result.items():
        print(f"deleted {n} rows from {tname}")


if __name__ == "__main__":
    main()
