"""Integration tests against the real Kaggle API.

Run with:
    uv run --group dev pytest tests/test_integration.py -v

Requires valid Kaggle credentials (~/.kaggle/kaggle.json). All tests are read-only.

Active competitions used (dawngamma's entered competitions):
  - ai-mathematical-olympiad-progress-prize-3
  - stanford-rna-3d-folding-2
  - deep-past-initiative-machine-translation
"""

import os
import pytest

# ---------------------------------------------------------------------------
# Credential guard — skip entire module if no credentials
# ---------------------------------------------------------------------------

HAS_CREDS = (
    os.path.exists(os.path.expanduser("~/.kaggle/kaggle.json"))
    or (os.getenv("KAGGLE_KEY") and os.getenv("KAGGLE_USERNAME"))
    or os.getenv("KAGGLE_KEY")  # newer KGAT_ tokens work without username
)

pytestmark = pytest.mark.skipif(
    not HAS_CREDS,
    reason="No Kaggle credentials found (set KAGGLE_KEY or create ~/.kaggle/kaggle.json)",
)


# ---------------------------------------------------------------------------
# Shared MCP fixture (real tools, no mocking)
# ---------------------------------------------------------------------------

@pytest.fixture(scope="module")
def mcp():
    from tests.conftest import MockMCP
    from kaggle_mcp import competitions, datasets, kernels, models, discussions, benchmarks

    m = MockMCP()
    competitions.register(m)
    datasets.register(m)
    kernels.register(m)
    models.register(m)
    discussions.register(m)
    benchmarks.register(m)
    return m


# ---------------------------------------------------------------------------
# Competitions — using dawngamma's active entered competitions
# ---------------------------------------------------------------------------

ACTIVE_COMP = "ai-mathematical-olympiad-progress-prize-3"
ACTIVE_COMP_2 = "stanford-rna-3d-folding-2"
ACTIVE_COMP_3 = "deep-past-initiative-machine-translation"


def test_competitions_list(mcp):
    result = mcp.tools["competitions_list"](search="mathematical olympiad")
    assert isinstance(result, str)
    assert len(result) > 0
    print(f"\n[competitions_list]\n{result[:300]}")


def test_competitions_list_entered(mcp):
    """List competitions the user has entered."""
    result = mcp.tools["competitions_list"](search="rna folding")
    assert isinstance(result, str)
    assert len(result) > 0
    print(f"\n[competitions_list entered]\n{result[:300]}")


def test_competition_files(mcp):
    """User has accepted rules for their active competitions."""
    result = mcp.tools["competition_files"](ACTIVE_COMP)
    assert isinstance(result, str)
    assert "Error" not in result or "No files" in result
    print(f"\n[competition_files]\n{result[:300]}")


def test_competition_leaderboard(mcp):
    result = mcp.tools["competition_leaderboard"](ACTIVE_COMP)
    assert isinstance(result, str)
    print(f"\n[competition_leaderboard]\n{result[:300]}")


def test_competition_leaderboard_rna(mcp):
    result = mcp.tools["competition_leaderboard"](ACTIVE_COMP_2)
    assert isinstance(result, str)
    print(f"\n[competition_leaderboard rna]\n{result[:300]}")


def test_competition_get(mcp):
    result = mcp.tools["competition_get"](ACTIVE_COMP)
    assert isinstance(result, str)
    assert "Error" not in result
    print(f"\n[competition_get]\n{result[:300]}")


def test_competition_get_translation(mcp):
    result = mcp.tools["competition_get"](ACTIVE_COMP_3)
    assert isinstance(result, str)
    assert "Error" not in result
    print(f"\n[competition_get translation]\n{result[:300]}")


# ---------------------------------------------------------------------------
# Datasets
# ---------------------------------------------------------------------------

def test_datasets_list(mcp):
    result = mcp.tools["datasets_list"](search="iris")
    assert isinstance(result, str)
    assert "No datasets found." not in result
    print(f"\n[datasets_list]\n{result[:300]}")


def test_dataset_files(mcp):
    result = mcp.tools["dataset_files"]("uciml", "iris")
    assert isinstance(result, str)
    assert len(result) > 0
    print(f"\n[dataset_files]\n{result[:300]}")


def test_dataset_metadata(mcp):
    result = mcp.tools["dataset_metadata"]("uciml", "iris")
    assert isinstance(result, str)
    assert len(result) > 0
    print(f"\n[dataset_metadata]\n{result[:300]}")


def test_dataset_get(mcp):
    result = mcp.tools["dataset_get"]("uciml", "iris")
    assert isinstance(result, str)
    assert "Error" not in result
    print(f"\n[dataset_get]\n{result[:300]}")


# ---------------------------------------------------------------------------
# Kernels
# ---------------------------------------------------------------------------

def test_kernels_list(mcp):
    result = mcp.tools["kernels_list"](search="titanic")
    assert isinstance(result, str)
    # Some KGAT_ tokens lack kernels-list permission
    print(f"\n[kernels_list]\n{result[:300]}")


def test_kernel_pull(mcp):
    # A well-known public kernel
    result = mcp.tools["kernel_pull"]("alexisbcook", "titanic-tutorial")
    assert isinstance(result, str)
    assert len(result) > 0
    print(f"\n[kernel_pull]\n{result[:300]}")


# ---------------------------------------------------------------------------
# Models
# ---------------------------------------------------------------------------

def test_models_list(mcp):
    result = mcp.tools["models_list"](search="bert")
    assert isinstance(result, str)
    assert "No models found." not in result
    print(f"\n[models_list]\n{result[:300]}")


def test_model_get(mcp):
    result = mcp.tools["model_get"]("google", "bert")
    assert isinstance(result, str)
    assert len(result) > 0
    print(f"\n[model_get]\n{result[:300]}")


def test_model_instances_list(mcp):
    result = mcp.tools["model_instances_list"]("google", "bert")
    assert isinstance(result, str)
    print(f"\n[model_instances_list]\n{result[:300]}")


# ---------------------------------------------------------------------------
# Discussions
# ---------------------------------------------------------------------------

def test_discussions_search(mcp):
    result = mcp.tools["discussions_search"]("mathematical olympiad solution")
    assert isinstance(result, str)
    assert "No discussions found." not in result
    print(f"\n[discussions_search]\n{result[:300]}")


def test_discussions_list_by_competition(mcp):
    result = mcp.tools["discussions_list"](competition=ACTIVE_COMP)
    assert isinstance(result, str)
    assert len(result) > 0
    print(f"\n[discussions_list]\n{result[:300]}")


def test_discussions_list_rna(mcp):
    result = mcp.tools["discussions_list"](competition=ACTIVE_COMP_2)
    assert isinstance(result, str)
    print(f"\n[discussions_list rna]\n{result[:300]}")


def test_discussions_list_recent(mcp):
    """Filter discussions updated in the last 24 hours."""
    result = mcp.tools["discussions_list"](competition=ACTIVE_COMP, since_hours=24)
    assert isinstance(result, str)
    # Active competition should have recent activity; if not, just verify no crash
    print(f"\n[discussions_list recent 24h]\n{result[:400]}")


def test_discussions_trending(mcp):
    result = mcp.tools["discussions_trending"]()
    assert isinstance(result, str)
    assert "Trending Discussions" in result
    print(f"\n[discussions_trending]\n{result[:300]}")


def test_discussions_solutions(mcp):
    result = mcp.tools["discussions_solutions"](competition=ACTIVE_COMP)
    assert isinstance(result, str)
    print(f"\n[discussions_solutions]\n{result[:300]}")


# ---------------------------------------------------------------------------
# Discussion detail — fixed with competition parameter
# ---------------------------------------------------------------------------

def test_discussion_detail_aimo(mcp):
    """Get full content of a known AIMO3 discussion."""
    result = mcp.tools["discussion_detail"](669690, competition=ACTIVE_COMP)
    assert isinstance(result, str)
    assert "not found" not in result.lower()
    assert len(result) > 100
    print(f"\n[discussion_detail aimo]\n{result[:400]}")


def test_discussion_detail_rna(mcp):
    result = mcp.tools["discussion_detail"](666382, competition=ACTIVE_COMP_2)
    assert isinstance(result, str)
    assert "not found" not in result.lower()
    print(f"\n[discussion_detail rna]\n{result[:400]}")


def test_discussion_detail_translation(mcp):
    result = mcp.tools["discussion_detail"](663210, competition=ACTIVE_COMP_3)
    assert isinstance(result, str)
    assert "not found" not in result.lower()
    print(f"\n[discussion_detail translation]\n{result[:400]}")


# ---------------------------------------------------------------------------
# Top kernels — open-source code ranking
# ---------------------------------------------------------------------------

def test_competition_top_kernels_aimo(mcp):
    """Top public kernels for AIMO3 (scores not exposed for active competitions)."""
    result = mcp.tools["competition_top_kernels"](ACTIVE_COMP)
    assert isinstance(result, str)
    assert "Error" not in result
    assert "Votes" in result
    print(f"\n[competition_top_kernels aimo]\n{result[:500]}")


def test_competition_top_kernels_rna(mcp):
    result = mcp.tools["competition_top_kernels"](ACTIVE_COMP_2)
    assert isinstance(result, str)
    assert "Error" not in result
    print(f"\n[competition_top_kernels rna]\n{result[:500]}")


# ---------------------------------------------------------------------------
# Benchmarks
# ---------------------------------------------------------------------------

def test_benchmark_leaderboard(mcp):
    # google/glue is a well-known public benchmark on Kaggle
    result = mcp.tools["benchmark_leaderboard"]("google", "glue")
    assert isinstance(result, str)
    print(f"\n[benchmark_leaderboard]\n{result[:300]}")
