import json
from pathlib import Path
from unittest.mock import patch

from typer.testing import CliRunner

from armorer.main import app
from armorer.tools import orchestrator


runner = CliRunner()


def test_clear_chat_backlog_removes_queue_files(tmp_path):
    home = tmp_path / "home"
    for dirname in ("inbox", "outbox", "status", "training_data"):
        (home / ".armorer" / dirname).mkdir(parents=True, exist_ok=True)
    (home / ".armorer" / "inbox" / "a.json").write_text("{}")
    (home / ".armorer" / "outbox" / "b.json").write_text("{}")
    (home / ".armorer" / "status" / "c.json").write_text("{}")
    (home / ".armorer" / "training_data" / "keep.json").write_text("{}")

    with patch("armorer.tools.orchestrator.Path.home", return_value=home):
        result = orchestrator.clear_chat_backlog(include_outbox=True, include_status=True)

    assert result["inbox_removed"] == 1
    assert result["outbox_removed"] == 1
    assert result["status_removed"] == 1
    assert not (home / ".armorer" / "inbox" / "a.json").exists()
    assert not (home / ".armorer" / "outbox" / "b.json").exists()
    assert not (home / ".armorer" / "status" / "c.json").exists()
    assert (home / ".armorer" / "training_data" / "keep.json").exists()


def test_clear_job_records_keeps_running_by_default(tmp_path):
    home = tmp_path / "home"
    jobs = home / ".armorer" / "jobs"
    jobs.mkdir(parents=True, exist_ok=True)
    (jobs / "done.json").write_text(json.dumps({"status": "completed"}))
    (jobs / "failed.json").write_text(json.dumps({"status": "failed"}))
    (jobs / "queued.json").write_text(json.dumps({"status": "queued"}))
    (jobs / "running.json").write_text(json.dumps({"status": "running"}))

    with patch("armorer.tools.orchestrator.Path.home", return_value=home):
        result = orchestrator.clear_job_records()

    assert sorted(result["removed"]) == ["done.json", "failed.json", "queued.json"]
    assert result["kept"] == ["running.json"]
    assert (jobs / "running.json").exists()


@patch("armorer.main.clear_chat_backlog")
def test_core_clear_queue_command(mock_clear):
    mock_clear.return_value = {
        "ok": True,
        "message": "Cleared chat backlog: 1 inbox, 2 outbox, 0 status file(s).",
    }

    result = runner.invoke(app, ["core", "clear-queue"])

    assert result.exit_code == 0
    assert "Cleared chat backlog" in result.stdout
    mock_clear.assert_called_once_with(include_outbox=True, include_status=True)


@patch("armorer.main.clear_job_records")
def test_core_clear_jobs_command(mock_clear):
    mock_clear.return_value = {
        "ok": True,
        "message": "Removed 2 job record(s); kept 1.",
        "kept": ["running.json"],
    }

    result = runner.invoke(app, ["core", "clear-jobs"])

    assert result.exit_code == 0
    assert "Removed 2 job record(s)" in result.stdout
    assert "running.json" in result.stdout
