#!/usr/bin/env python
"""Seed/sync the connector catalog (connectors + actions + triggers) to the database.

Usage:
  python -m scripts.sync_connector_catalog
  python -m scripts.sync_connector_catalog --connector stripe
  python -m scripts.sync_connector_catalog --dry-run
  python -m scripts.sync_connector_catalog --list
"""
from __future__ import annotations

import asyncio
import argparse
import os
import sys

sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__))))


async def run_sync(
    connector_key: str | None = None,
    dry_run: bool = False,
    list_only: bool = False,
) -> int:
    from src.domain.connectors.providers import CONNECTORS
    from src.core.database import async_session_factory
    from src.domain.connectors.repository import ConnectorRepository
    from src.domain.connectors.service import ConnectorService
    from src.integrations.cloud_control_client import CloudControlClient

    if list_only:
        for key, cdef in CONNECTORS.items():
            actions = ", ".join(a.slug for a in cdef.actions) or "(none)"
            triggers = ", ".join(t.event_type for t in cdef.triggers) or "(none)"
            print(f"  {key:12s}  auth={cdef.auth_type:8s}  actions=[{actions}]  triggers=[{triggers}]")
        return 0

    targets = (
        {connector_key: CONNECTORS[connector_key]}
        if connector_key
        else CONNECTORS
    )
    if connector_key and connector_key not in CONNECTORS:
        print(f"FAIL: unknown connector '{connector_key}'. Available: {', '.join(CONNECTORS)}")
        return 1

    if dry_run:
        print("DRY-RUN: no changes will be committed")

    synced = failed = 0

    async with async_session_factory() as db:
        svc = ConnectorService(
            repo=ConnectorRepository(db),
            cloud_client=CloudControlClient(),
        )
        for key, cdef in targets.items():
            try:
                if not dry_run:
                    await svc.sync_catalog_defaults()
                action_names = [a.slug for a in cdef.actions]
                trigger_names = [t.event_type for t in cdef.triggers]
                print(
                    f"  [OK] {key}"
                    f"  actions={action_names}"
                    f"  triggers={trigger_names}"
                )
                synced += 1
            except Exception as exc:
                print(f"  [FAIL] {key}: {exc}")
                failed += 1

        if not dry_run and failed == 0:
            await db.commit()

    print(f"\nResult: synced={synced} failed={failed}")
    return 1 if failed > 0 else 0


def main() -> int:
    parser = argparse.ArgumentParser(description="Sync connector catalog to database")
    parser.add_argument("--connector", metavar="KEY", help="Sync only this connector (e.g. stripe)")
    parser.add_argument("--dry-run", action="store_true", help="Do not commit changes")
    parser.add_argument("--list", action="store_true", help="List available connectors and exit")
    args = parser.parse_args()
    return asyncio.run(run_sync(
        connector_key=args.connector,
        dry_run=args.dry_run,
        list_only=args.list,
    ))


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