"""Universal loader: dumps every scraped JSON from data/raw/domrf_full/ into Postgres
as JSONB rows in domrf_raw_endpoints. Idempotent (UPSERT by snapshot+section+endpoint).

Usage:
    PG_HOST=localhost PG_PORT=15432 PGPASSWORD=... python data/sql/32_load_domrf_raw.py
"""
import os, json, subprocess, sys, datetime

HERE = os.path.dirname(os.path.abspath(__file__))
ROOT = os.path.join(HERE, '..', 'raw', 'domrf_full')
PG_PORT = os.environ.get('PG_PORT', '5432')
PG_USER = os.environ.get('PG_USER', 'gendesign')
PG_DB   = os.environ.get('PG_DB',   'gendesign')
PG_PASS = os.environ.get('PGPASSWORD', '')
SNAP    = os.environ.get('SNAPSHOT_DATE', datetime.date.today().isoformat())


def psql(sql):
    cmd = ['docker', 'run', '--rm', '-i', '-e', f'PGPASSWORD={PG_PASS}',
           'postgres:16-alpine', 'psql', '-h', 'host.docker.internal', '-p', PG_PORT,
           '-U', PG_USER, '-d', PG_DB, '-v', 'ON_ERROR_STOP=1', '--quiet']
    res = subprocess.run(cmd, input=sql, capture_output=True, text=True, encoding='utf-8')
    if res.returncode != 0:
        print('psql FAILED:', res.stderr[-1500:], file=sys.stderr)
        raise SystemExit(res.returncode)
    return res.stdout


def psql_stdin(sql, stdin_data):
    """Use psql with COPY via stdin to load big JSONs (avoids cmdline length limits)."""
    cmd = ['docker', 'run', '--rm', '-i', '-e', f'PGPASSWORD={PG_PASS}',
           'postgres:16-alpine', 'psql', '-h', 'host.docker.internal', '-p', PG_PORT,
           '-U', PG_USER, '-d', PG_DB, '-v', 'ON_ERROR_STOP=1', '--quiet']
    res = subprocess.run(cmd, input=stdin_data, capture_output=True, text=True, encoding='utf-8')
    if res.returncode != 0:
        print('psql FAILED:', res.stderr[-1500:], file=sys.stderr)
        raise SystemExit(res.returncode)
    return res.stdout


def main():
    schema = open(os.path.join(HERE, '31_schema_domrf_raw.sql'), encoding='utf-8').read()
    psql(schema)
    print('schema applied')

    loaded = 0
    skipped = 0
    by_section = {}

    for section in sorted(os.listdir(ROOT)):
        sec_dir = os.path.join(ROOT, section)
        if not os.path.isdir(sec_dir):
            continue
        files = [f for f in os.listdir(sec_dir) if f.endswith('.json')]
        for fname in sorted(files):
            fpath = os.path.join(sec_dir, fname)
            try:
                text = open(fpath, encoding='utf-8').read()
                json.loads(text)  # validate
            except Exception as e:
                print(f'  SKIP invalid JSON: {section}/{fname}: {e}')
                skipped += 1
                continue
            endpoint = fname[:-5]  # strip .json
            # Use COPY ... FROM STDIN for safe binary insertion
            # Use psycopg-style escape: \\ → \\\\, replace tabs/newlines in JSON keys
            # Easier: pass JSON via stdin to a Python heredoc-style INSERT
            sql = f"""
INSERT INTO domrf_raw_endpoints (snapshot_date, section, endpoint, source_url, payload, payload_size, fetched_at)
VALUES ('{SNAP}', $sec${section}$sec$, $end${endpoint}$end$, NULL, $j${text}$j$::jsonb, {len(text)}, NOW())
ON CONFLICT (snapshot_date, section, endpoint) DO UPDATE SET
    payload = EXCLUDED.payload,
    payload_size = EXCLUDED.payload_size,
    fetched_at = NOW();
"""
            psql_stdin('', sql)
            loaded += 1
            by_section.setdefault(section, 0)
            by_section[section] += 1

    print(f'\nLOADED {loaded} files, SKIPPED {skipped}')
    print('--- by section ---')
    for s, n in sorted(by_section.items()):
        print(f'  {s:22s} {n}')

    # Final summary from DB
    print('\n--- DB summary ---')
    out = psql(f"""
        SELECT section, COUNT(*) AS endpoints, pg_size_pretty(SUM(payload_size)::bigint) AS total
        FROM domrf_raw_endpoints
        WHERE snapshot_date = '{SNAP}'
        GROUP BY section
        ORDER BY section;
    """)
    print(out)


if __name__ == '__main__':
    main()
