"""Tests for resume training and W&B integration."""

from pathlib import Path

from typer.testing import CliRunner

from soup_cli.cli import app
from soup_cli.commands.train import _resolve_checkpoint

runner = CliRunner()


# --- _resolve_checkpoint ---

def test_resolve_checkpoint_auto_finds_latest(tmp_path: Path):
    """auto should find the latest checkpoint by number."""
    output_dir = tmp_path / "output"
    output_dir.mkdir()
    (output_dir / "checkpoint-100").mkdir()
    (output_dir / "checkpoint-200").mkdir()
    (output_dir / "checkpoint-50").mkdir()

    result = _resolve_checkpoint("auto", str(output_dir))
    assert result == str(output_dir / "checkpoint-200")


def test_resolve_checkpoint_auto_with_experiment_name(tmp_path: Path):
    """auto should look inside experiment_name subdirectory."""
    output_dir = tmp_path / "output"
    exp_dir = output_dir / "my-experiment"
    exp_dir.mkdir(parents=True)
    (exp_dir / "checkpoint-100").mkdir()
    (exp_dir / "checkpoint-300").mkdir()

    result = _resolve_checkpoint("auto", str(output_dir), experiment_name="my-experiment")
    assert result == str(exp_dir / "checkpoint-300")


def test_resolve_checkpoint_auto_no_checkpoints(tmp_path: Path):
    """auto should return None if no checkpoints exist."""
    output_dir = tmp_path / "output"
    output_dir.mkdir()

    result = _resolve_checkpoint("auto", str(output_dir))
    assert result is None


def test_resolve_checkpoint_auto_missing_dir(tmp_path: Path):
    """auto should return None if output dir doesn't exist."""
    result = _resolve_checkpoint("auto", str(tmp_path / "nonexistent"))
    assert result is None


def test_resolve_checkpoint_direct_path(tmp_path: Path):
    """Direct path to checkpoint should be returned as-is."""
    checkpoint = tmp_path / "checkpoint-100"
    checkpoint.mkdir()

    result = _resolve_checkpoint(str(checkpoint), str(tmp_path))
    assert result == str(checkpoint)


def test_resolve_checkpoint_direct_path_nonexistent():
    """Nonexistent direct path should return None."""
    result = _resolve_checkpoint("/nonexistent/checkpoint-100", "/output")
    assert result is None


def test_resolve_checkpoint_auto_ignores_non_checkpoint_dirs(tmp_path: Path):
    """auto should ignore directories that don't start with checkpoint-."""
    output_dir = tmp_path / "output"
    output_dir.mkdir()
    (output_dir / "checkpoint-100").mkdir()
    (output_dir / "logs").mkdir()
    (output_dir / "runs").mkdir()

    result = _resolve_checkpoint("auto", str(output_dir))
    assert result == str(output_dir / "checkpoint-100")


# --- CLI flags ---

def test_train_resume_flag_in_help():
    result = runner.invoke(app, ["train", "--help"])
    assert result.exit_code == 0
    assert "resume" in result.output.lower()


def test_train_wandb_flag_in_help():
    result = runner.invoke(app, ["train", "--help"])
    assert result.exit_code == 0
    assert "wandb" in result.output.lower()


def test_train_resume_nonexistent_checkpoint(tmp_path: Path):
    """Resume with nonexistent checkpoint path should fail (after config validation)."""
    config_file = tmp_path / "soup.yaml"
    config_file.write_text("""
base: meta-llama/Llama-3.1-8B
data:
  train: ./data.jsonl
""")
    result = runner.invoke(
        app, ["train", "--config", str(config_file), "--resume", "/nonexistent/checkpoint"]
    )
    assert result.exit_code == 1
    assert "no checkpoint found" in result.output.lower()
