#!/usr/bin/env python3
"""
LDR Research Script

Reads a research query from stdin and uses Local Deep Research to find
relevant documentation, sources, and context. Returns JSON with the
research output.

Usage:
    # Pipe a query from stdin
    echo "What is RAG?" | python scripts/ldr-research.py

    # Or pass a file
    python scripts/ldr-research.py < query.txt

    # With CLI arguments (easier local testing)
    python scripts/ldr-research.py --provider openrouter --model gpt-4o < query.txt

Output: JSON with research results, sources, and findings.

Environment variables (can be overridden by CLI args):
    OPENROUTER_API_KEY - API key for OpenRouter
    SERPER_API_KEY - API key for Serper.dev search
    LDR_PROVIDER - LLM provider (default: openrouter)
    LDR_SEARCH_TOOL - Search tool (default: serper)
    LDR_RESEARCH_MODEL - Model name (default: google/gemini-2.0-flash-001 for openrouter)
    LDR_STRATEGY - Search strategy (default: langgraph-agent)

Note: This uses the programmatic API and does NOT require a running LDR server.
"""

import argparse
import json
import os
import sys


def make_serializable(obj):
    """Convert objects to JSON-serializable format."""
    if obj is None:
        return None
    if isinstance(obj, (str, int, float, bool)):
        return obj
    if isinstance(obj, dict):
        return {k: make_serializable(v) for k, v in obj.items()}
    if isinstance(obj, (list, tuple)):
        return [make_serializable(item) for item in obj]
    # Handle LangChain Document objects
    if hasattr(obj, "page_content") and hasattr(obj, "metadata"):
        return {
            "content": obj.page_content,
            "metadata": make_serializable(obj.metadata),
        }
    # Handle other objects with __dict__
    if hasattr(obj, "__dict__"):
        return make_serializable(obj.__dict__)
    # Fallback to string representation
    return str(obj)


def parse_args():
    parser = argparse.ArgumentParser(
        description="Run LDR research on a query read from stdin"
    )
    parser.add_argument(
        "--provider",
        default=os.environ.get("LDR_PROVIDER", "openrouter"),
        help="LLM provider (default: openrouter)",
    )
    parser.add_argument(
        "--search-tool",
        default=os.environ.get("LDR_SEARCH_TOOL", "serper"),
        help="Search tool (default: serper)",
    )
    parser.add_argument(
        "--model",
        default=os.environ.get("LDR_RESEARCH_MODEL"),
        help="Model name (default: provider's default)",
    )
    parser.add_argument(
        "--iterations",
        type=int,
        default=None,
        help=(
            "Number of research iterations. If unset, the strategy uses "
            "its own default (e.g. langgraph-agent reads "
            "langgraph_agent.max_iterations from settings)."
        ),
    )
    parser.add_argument(
        "--strategy",
        default=os.environ.get("LDR_STRATEGY", "langgraph-agent"),
        help="Search strategy name (default: langgraph-agent)",
    )
    return parser.parse_args()


def main():
    args = parse_args()

    # Read query from stdin
    query = sys.stdin.read().strip()
    if not query:
        print(json.dumps({"error": "No query provided on stdin"}))
        sys.exit(1)

    # Default model for OpenRouter if not specified
    model_name = args.model
    if not model_name and args.provider == "openrouter":
        model_name = "google/gemini-2.0-flash-001"

    # Check required API keys
    if args.provider == "openrouter" and not os.environ.get(
        "OPENROUTER_API_KEY"
    ):
        print(json.dumps({"error": "OPENROUTER_API_KEY not set"}))
        sys.exit(1)

    if args.search_tool == "serper" and not os.environ.get("SERPER_API_KEY"):
        print(json.dumps({"error": "SERPER_API_KEY not set"}))
        sys.exit(1)

    try:
        from local_deep_research.api import quick_summary
        from local_deep_research.api.settings_utils import (
            create_settings_snapshot,
        )

        # Build settings overrides
        overrides = {
            "search.tool": args.search_tool,
            "llm.provider": args.provider,
        }
        if model_name:
            overrides["llm.model"] = model_name

        # Add API keys from environment
        if os.environ.get("OPENROUTER_API_KEY"):
            overrides["llm.openrouter.api_key"] = os.environ[
                "OPENROUTER_API_KEY"
            ]
        if os.environ.get("SERPER_API_KEY"):
            overrides["search.engine.web.serper.api_key"] = os.environ[
                "SERPER_API_KEY"
            ]

        settings = create_settings_snapshot(overrides=overrides)

        # Build kwargs
        kwargs = {
            "query": query,
            "provider": args.provider,
            "search_tool": args.search_tool,
            "settings_snapshot": settings,
            "programmatic_mode": True,
            "search_strategy": args.strategy,
        }
        if model_name:
            kwargs["model_name"] = model_name
        if args.iterations is not None:
            kwargs["iterations"] = args.iterations

        result = quick_summary(**kwargs)

        # Use formatted_findings if available (already properly formatted with sources)
        # Fall back to summary if not
        research_output = result.get("formatted_findings") or result.get(
            "summary", str(result)
        )

        # Build output - make sure everything is JSON serializable
        output = {
            "research": research_output,
            "sources": make_serializable(result.get("sources", [])),
            "findings": make_serializable(result.get("findings", [])),
            "iterations": result.get("iterations"),
        }

        print(json.dumps(output))

    except Exception as e:
        print(json.dumps({"error": str(e)}))
        sys.exit(1)


if __name__ == "__main__":
    main()
