"""
Tiny CLI helper to run Analyzer's classify_pii without an MCP client.

Usage:
  python -X utf8 tools/classify_pii.py data/example.jpeg [--model gpt-4o-mini]
Requires OPENAI_API_KEY in the environment.
"""
from __future__ import annotations

import argparse
import asyncio
import json
import os
import sys
from pathlib import Path
from datetime import datetime, timezone
import platform
import pathlib
import sys as _sys

# Ensure repository root is on sys.path when run from tools/
_REPO_ROOT = pathlib.Path(__file__).resolve().parents[1]
if str(_REPO_ROOT) not in _sys.path:
    _sys.path.insert(0, str(_REPO_ROOT))


def main() -> int:
    parser = argparse.ArgumentParser(description="Run Analyzer classify_pii on an image")
    parser.add_argument("image", help="Path to input image")
    parser.add_argument(
        "--model",
        default=os.getenv("OPENAI_ANALYZER_MODEL", os.getenv("OPENAI_VISION_MODEL", "gpt-4o-mini")),
        help="OpenAI model for Analyzer (default: env OPENAI_ANALYZER_MODEL or gpt-4o-mini)",
    )
    parser.add_argument(
        "--log-to-auditor",
        action="store_true",
        help="Also log instances to Auditor via MCP stdio",
    )
    parser.add_argument(
        "--log-timeout",
        type=float,
        default=5.0,
        help="Timeout in seconds for the MCP logging step (default: 5)",
    )
    parser.add_argument(
        "--log-mode",
        choices=["auto", "mcp", "file"],
        default="auto",
        help="Where to log when --log-to-auditor is set: 'mcp' (Auditor server), 'file' (JSONL directly), or 'auto' (try MCP then file). Default: auto",
    )
    parser.add_argument(
        "--quiet-logging",
        action="store_true",
        help="Suppress non-fatal logging warnings (MCP/file logging failures)",
    )
    args = parser.parse_args()

    ipath = Path(args.image)
    if not ipath.exists():
        print(f"error: image not found: {ipath}", file=sys.stderr)
        return 2

    # Set model for this process (the analyzer reads env var)
    os.environ["OPENAI_ANALYZER_MODEL"] = args.model
    # Keep legacy var for compatibility
    os.environ["OPENAI_VISION_MODEL"] = args.model

    try:
        from mcp.servers.analyzer_server import classify_pii  # type: ignore
    except Exception as e:
        print(f"error: failed to import analyzer: {e}", file=sys.stderr)
        return 1

    result = classify_pii(str(ipath))
    print(json.dumps(result, ensure_ascii=False, indent=2))

    def _log_to_file() -> bool:
        try:
            log_dir = _REPO_ROOT / "artifacts" / "logs"
            log_dir.mkdir(parents=True, exist_ok=True)
            entry = {
                "timestamp": datetime.now(timezone.utc).isoformat(),
                "image": str(ipath),
                # "location": str(ipath.resolve()),  # optional
                "instances": result,
                "meta": (result or {}).get("meta", {}),
                "workstation": {
                    "os": platform.platform(),
                    "python": platform.python_version(),
                    "machine": platform.machine(),
                    "processor": platform.processor() or platform.machine(),
                },
            }
            with (log_dir / "instances.jsonl").open("a", encoding="utf-8") as f:
                f.write(json.dumps(entry) + "\n")
            return True
        except Exception as e:  # pragma: no cover
            if not args.quiet_logging:
                print(f"warning: file logging failed: {e}", file=sys.stderr)
            return False

    if args.log_to_auditor and isinstance(result, dict):
        did_log = False
        if args.log_mode in ("auto", "mcp"):
            did_log = False
        try:
            from mcp.client.session import ClientSession  # type: ignore
            from mcp.client.stdio import stdio_client, StdioServerParameters  # type: ignore
        except Exception as e:
            if args.log_mode == "mcp" and not args.quiet_logging:
                print(f"warning: cannot log to auditor (mcp sdk missing): {e}", file=sys.stderr)
        else:
            async def _log():
                params = StdioServerParameters(
                    command=sys.executable,
                    args=["-m", "mcp.servers.auditor_server"],
                )
                try:
                    async with stdio_client(params) as (read, write):
                        async with ClientSession(read, write) as session:
                            # Initialize with timeout
                            try:
                                await asyncio.wait_for(session.initialize(), timeout=max(0.5, args.log_timeout))
                            except Exception as e:
                                if not args.quiet_logging:
                                    print(f"warning: auditor init failed/timed out: {e}", file=sys.stderr)
                                return
                            # Call tool with timeout
                            try:
                                await asyncio.wait_for(
                                    session.call_tool(
                                        "log_instances",
                                        {"image_path": str(ipath), "instances": result},
                                    ),
                                    timeout=max(0.5, args.log_timeout),
                                )
                            except Exception as e:  # pragma: no cover
                                if not args.quiet_logging:
                                    print(f"warning: logging failed/timed out: {e}", file=sys.stderr)
                                return False
                            # Try to close/shutdown without blocking exit (best-effort)
                            try:
                                close = getattr(session, "close", None)
                                if callable(close):
                                    await asyncio.wait_for(close(), timeout=1.0)
                            except Exception:
                                pass
                    return True
                except Exception as e:
                    if not args.quiet_logging:
                        print(f"warning: auditor stdio client error: {e}", file=sys.stderr)
                    return False

            try:
                did_log = bool(asyncio.run(_log()))
            except KeyboardInterrupt:
                pass
            except Exception:
                did_log = False

        # Fallback to file logging when in auto mode
        if not did_log and args.log_mode in ("auto", "file"):
            _ = _log_to_file()
    return 0


if __name__ == "__main__":
    raise SystemExit(main())
