#!/usr/bin/env python3
"""Export a legacy SQLite database as deterministic JSON Lines for staging.

The default omits credential/ciphertext columns. --include-encrypted retains old
ciphertext only for a controlled offline transform; it never decrypts or logs it.
"""
from __future__ import annotations

import argparse
import base64
import datetime as dt
import hashlib
import json
import sqlite3
import sys
from pathlib import Path

SENSITIVE_MARKERS = ("password", "secret", "api_key", "raw_key", "totp", "backup_codes", "headers_template")


def encode(value):
    if isinstance(value, bytes):
        return {"$binary_base64": base64.b64encode(value).decode("ascii")}
    if isinstance(value, (dt.date, dt.datetime)):
        return value.isoformat()
    return value


def main() -> None:
    parser = argparse.ArgumentParser()
    parser.add_argument("database", type=Path)
    parser.add_argument("--source-system", default="python-gateway")
    parser.add_argument("--include-encrypted", action="store_true")
    args = parser.parse_args()
    if not args.database.is_file():
        parser.error("SQLite database does not exist")
    connection = sqlite3.connect(f"file:{args.database}?mode=ro", uri=True)
    connection.row_factory = sqlite3.Row
    tables = [row[0] for row in connection.execute("SELECT name FROM sqlite_master WHERE type='table' AND name NOT LIKE 'sqlite_%' ORDER BY name")]
    for table in tables:
        columns = [row[1] for row in connection.execute(f'PRAGMA table_info("{table}")')]
        id_column = "id" if "id" in columns else None
        if id_column is None:
            print(f"skip table without id: {table}", file=sys.stderr)
            continue
        selected = [column for column in columns if args.include_encrypted or not any(marker in column.lower() for marker in SENSITIVE_MARKERS)]
        order = f' ORDER BY "{id_column}"'
        query = "SELECT " + ",".join(f'"{column}"' for column in selected) + f' FROM "{table}"' + order
        for row in connection.execute(query):
            data = {column: encode(row[column]) for column in selected}
            record = {"source_system": args.source_system, "entity_type": table, "legacy_id": str(row[id_column]), "data": data}
            canonical = json.dumps(record, ensure_ascii=False, sort_keys=True, separators=(",", ":"))
            record["checksum"] = hashlib.sha256(canonical.encode()).hexdigest()
            print(json.dumps(record, ensure_ascii=False, sort_keys=True, separators=(",", ":")))


if __name__ == "__main__":
    main()
