#!/usr/bin/env python3
"""
RDF - Research Development Framework CLI (v4.0 Agent Edition)

Unified entrypoint for all RDF commands. Optimized for Claude Code orchestration.

Usage:
    rdf <command> [options]

Core Commands:
    ingest      Add documents to library
    search      Search the library
    fetch       Retrieve bounded chunk text
    research    Autonomous research
    quotes      Extract evidence
    outline     Generate book outline
    book        Book compilation workflow
    essay       Essay generation
    write       Universal entry point (infers essay/book)
    validate    Claim verification
    polish      Style refinement
    queue       Review queue management
    status      Workflow state

Utility Commands:
    health      Library health scan
    edit-meta   Metadata corrections
    assess      Mechanical document assessment
    graph       Knowledge graph queries (JSON)
    diff        File comparison
    context     Agent session warm-start (resume context)
    capabilities Agent capability manifest (bootstrapping)
    entity      Entity/concept management (duplicates, merge, alias)
    export      Export bibliography (BibTeX, RIS, CSL-JSON)
"""

import sys
import os
import subprocess
import argparse
import json
from pathlib import Path

# Add pipeline to path
SCRIPT_DIR = Path(__file__).parent.resolve()
PIPELINE_DIR = SCRIPT_DIR / "pipeline"
sys.path.insert(0, str(SCRIPT_DIR))

# Command mapping to underlying scripts
COMMAND_MAP = {
    # Core commands
    "ingest": ("ingest_documents.py", "Add documents to library"),
    "search": ("search_export.py", "Search the library"),
    "fetch": ("fetch.py", "Retrieve bounded chunk text"),
    "research": ("research_agent.py", "Autonomous research"),
    "quotes": ("extract_quotes.py", "Extract evidence"),
    "outline": ("outline.py", "Generate book outline"),
    "book": ("book.py", "Book compilation workflow"),
    "essay": ("essay.py", "Essay generation"),
    "write": ("write.py", "Universal entry point"),
    "validate": ("validate_draft.py", "Claim verification"),
    "polish": ("polish_draft.py", "Style refinement"),
    "queue": ("review_queue.py", "Review queue management"),
    "status": ("status.py", "Workflow state"),

    # Utility commands
    "health": ("library_gardener.py", "Library health scan"),
    "edit-meta": ("edit_metadata.py", "Metadata corrections"),
    "assess": ("assess.py", "Mechanical document assessment"),
    "graph": ("knowledge_graph.py", "Knowledge graph queries"),
    "diff": ("diff.py", "File comparison"),
    "config": ("configure.py", "Configuration management"),
    "context": ("context.py", "Agent session warm-start"),
    "capabilities": ("capabilities.py", "Agent capability manifest"),
    "entity": ("entity.py", "Entity/concept management"),
    "export": ("export_bibliography.py", "Export bibliography (BibTeX, RIS, CSL-JSON)"),
}

# Default flags for certain commands (v4.0 safety defaults)
DEFAULT_FLAGS = {
    "research": ["--strict-library-only"],  # Library only by default
    "book": ["--autonomy", "supervised"],   # Supervised by default
    "essay": ["--autonomy", "full"],        # Full autonomy by default
}


def get_version():
    """Return RDF version."""
    return "4.0.0"


def print_help():
    """Print main help message."""
    print(__doc__)
    print(f"\nVersion: {get_version()}")
    print("\nUse 'rdf <command> --help' for command-specific help.")


def print_json_error(code: str, message: str, advice: str = None):
    """Print error in JSON format."""
    response = {
        "status": "error",
        "code": code,
        "message": message,
    }
    if advice:
        response["actionable_advice"] = advice
    print(json.dumps(response, indent=2))


def run_command(command: str, args: list) -> int:
    """Run a subcommand with arguments."""
    if command not in COMMAND_MAP:
        print_json_error(
            "UNKNOWN_COMMAND",
            f"Unknown command: {command}",
            f"Available commands: {', '.join(sorted(COMMAND_MAP.keys()))}"
        )
        return 1

    script_name, _ = COMMAND_MAP[command]
    script_path = PIPELINE_DIR / script_name

    # Check if script exists
    if not script_path.exists():
        # Some commands may be new and need to be created
        print_json_error(
            "SCRIPT_NOT_FOUND",
            f"Script not found: {script_path}",
            f"This command may not be implemented yet."
        )
        return 1

    # Build command with default flags
    cmd = [sys.executable, str(script_path)]

    # Add default flags if not overridden
    if command in DEFAULT_FLAGS:
        for flag in DEFAULT_FLAGS[command]:
            # Check if flag is already in args
            if flag.startswith("--"):
                flag_name = flag.split("=")[0]
                if not any(a.startswith(flag_name) for a in args):
                    cmd.append(flag)
            else:
                cmd.append(flag)

    cmd.extend(args)

    # Run the command
    try:
        result = subprocess.run(cmd, cwd=SCRIPT_DIR)
        return result.returncode
    except KeyboardInterrupt:
        print("\nInterrupted.")
        return 130
    except Exception as e:
        print_json_error("EXECUTION_ERROR", str(e))
        return 1


def main():
    """Main entry point."""
    if len(sys.argv) < 2:
        print_help()
        return 0

    command = sys.argv[1]
    args = sys.argv[2:]

    # Handle special cases
    if command in ["-h", "--help", "help"]:
        print_help()
        return 0

    if command in ["-v", "--version", "version"]:
        print(f"RDF version {get_version()}")
        return 0

    if command == "commands":
        # List all commands in JSON format
        commands = {
            "core": {k: v[1] for k, v in COMMAND_MAP.items()
                    if k in ["ingest", "search", "fetch", "research", "quotes",
                            "outline", "book", "essay", "write", "validate",
                            "polish", "queue", "status"]},
            "utility": {k: v[1] for k, v in COMMAND_MAP.items()
                       if k in ["health", "edit-meta", "assess", "graph", "diff"]}
        }
        print(json.dumps(commands, indent=2))
        return 0

    return run_command(command, args)


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