"""CLI entry point for the modernized legacy PentestGPT.

pentestgpt-legacy                       # interactive session (auto-picks models)
pentestgpt-legacy --list-models         # show the supported-model registry
pentestgpt-legacy --smoke-test          # live round-trip every configured model
pentestgpt-legacy --reasoning-model claude-opus-4-8 --parsing-model gemini-3.5-flash
pentestgpt-legacy --reasoning-model ollama:qwen3 --base-url http://localhost:11434/v1
"""

from __future__ import annotations

import argparse
import os
import sys

from pentestgpt_legacy._version import __version__
from pentestgpt_legacy.config import (
    configured_providers,
    default_parsing_model,
    default_reasoning_model,
)
from pentestgpt_legacy.llm.registry import PROVIDERS, models_by_provider, resolve


def _create_parser() -> argparse.ArgumentParser:
    parser = argparse.ArgumentParser(
        prog="pentestgpt-legacy",
        description="PentestGPT (modernized legacy) — interactive, multi-LLM pentest assistant.",
    )
    parser.add_argument(
        "--reasoning-model",
        type=str,
        default=None,
        help="Model for reasoning / the Pentesting Task Tree.",
    )
    parser.add_argument(
        "--parsing-model", type=str, default=None, help="Model for summarizing tool/web output."
    )
    parser.add_argument(
        "--generation-model",
        type=str,
        default=None,
        help="Model for expanding tasks into steps (defaults to reasoning model).",
    )
    parser.add_argument(
        "--base-url",
        type=str,
        default=None,
        help="Override the API base URL for the selected models' provider "
        "(useful for Ollama / OpenAI-compatible endpoints).",
    )
    parser.add_argument("--log-dir", type=str, default="logs", help="Directory for logs.")
    parser.add_argument(
        "--list-models", action="store_true", help="List all supported models and exit."
    )
    parser.add_argument(
        "--smoke-test",
        action="store_true",
        help="Make a real API call to every configured model and report a matrix.",
    )
    parser.add_argument(
        "--provider",
        type=str,
        default=None,
        help="Restrict --smoke-test to one provider (e.g. openai, anthropic).",
    )
    parser.add_argument(
        "--model", type=str, default=None, help="Restrict --smoke-test to a single model id."
    )
    parser.add_argument("--version", action="version", version=f"pentestgpt-legacy {__version__}")
    return parser


def display_models() -> None:
    """Render the supported-model registry grouped by provider."""
    ready = set(configured_providers())
    print(f"\nPentestGPT (modernized legacy) v{__version__} — supported models\n")
    for provider_key, specs in models_by_provider().items():
        info = PROVIDERS[provider_key]
        status = "configured" if provider_key in ready else "no key"
        env_hint = ""
        if info.requires_key and provider_key not in ready and info.env:
            env_hint = f"  (set {info.env})"
        print(f"== {info.label} [{status}]{env_hint} ==")
        for spec in specs:
            flag = "legacy" if spec.legacy else spec.tier
            ctx = f"{spec.context_window // 1000}K ctx"
            note = f" — {spec.notes}" if spec.notes else ""
            print(f"   {spec.id:<32} [{flag:<8}] {ctx}{note}")
        print()
    print("Local models: pass 'ollama:<model>' (e.g. ollama:qwen3) with --base-url if needed.\n")


def _apply_base_url_override(models: list[str], base_url: str) -> None:
    """Set the per-provider *_BASE_URL env override for the selected models."""
    for model_name in models:
        spec = resolve(model_name)
        if spec is None:
            continue
        info = PROVIDERS.get(spec.provider)
        if info is None or (info.base_url is None and spec.provider in ("anthropic", "gemini")):
            print(f"Note: --base-url is not applicable to provider '{spec.provider}'.")
            continue
        os.environ[f"{spec.provider.upper()}_BASE_URL"] = base_url


def run_interactive(args: argparse.Namespace) -> None:
    reasoning_model = args.reasoning_model or default_reasoning_model()
    parsing_model = args.parsing_model or default_parsing_model()

    if reasoning_model is None or parsing_model is None:
        print(
            "No LLM provider is configured. Set an API key (e.g. OPENAI_API_KEY, "
            "ANTHROPIC_API_KEY, GEMINI_API_KEY, DEEPSEEK_API_KEY) in your environment "
            "or .env file, or run with --list-models to see options.",
            file=sys.stderr,
        )
        sys.exit(1)

    if args.base_url:
        selected = [m for m in (reasoning_model, parsing_model, args.generation_model) if m]
        _apply_base_url_override(selected, args.base_url)

    # Imported lazily so --list-models / --smoke-test don't require prompt_toolkit/rich.
    from pentestgpt_legacy.utils.pentest_gpt import pentestGPT

    try:
        session = pentestGPT(
            log_dir=args.log_dir,
            reasoning_model=reasoning_model,
            parsing_model=parsing_model,
            generation_model=args.generation_model,
        )
        session.main()
    except Exception as e:
        print(f"PentestGPT execution failed: {e}", file=sys.stderr)
        sys.exit(1)


def main() -> None:
    args = _create_parser().parse_args()

    if args.list_models:
        display_models()
        return

    if args.smoke_test:
        from pentestgpt_legacy.smoke_test import run_smoke_test

        sys.exit(run_smoke_test(provider=args.provider, model=args.model))

    run_interactive(args)


if __name__ == "__main__":
    main()
