from __future__ import annotations

from pathlib import Path

from aicd.kit.workspace_metrics import op_code_lines, op_document_words, run_operation


def test_code_lines_counts_by_extension(tmp_path: Path) -> None:
    src = tmp_path / "proj"
    src.mkdir()
    (src / "a.py").write_text("a\nb\nc\n\n", encoding="utf-8")
    (src / "b.js").write_text("x\ny\n", encoding="utf-8")
    nested = src / "pkg"
    nested.mkdir()
    (nested / "c.py").write_text("# hi\n", encoding="utf-8")
    r = op_code_lines(
        {"root": str(src), "extensions": [".py", ".js"], "max_files": 100}
    )
    assert r["ok"] is True
    assert r["total_files"] == 3
    assert r["by_extension"][".py"]["lines"] == 5
    assert r["by_extension"][".js"]["lines"] == 2
    assert r["total_non_blank_lines"] >= 3


def test_code_lines_skips_exclude_dirs(tmp_path: Path) -> None:
    root = tmp_path / "r"
    root.mkdir()
    (root / "ok.py").write_text("1\n", encoding="utf-8")
    bad = root / "node_modules" / "x"
    bad.mkdir(parents=True)
    (bad / "nope.py").write_text("99\n", encoding="utf-8")
    r = op_code_lines({"root": str(root), "extensions": [".py"]})
    assert r["ok"] is True
    assert r["total_files"] == 1
    assert r["total_lines"] == 1


def test_document_words_glob(tmp_path: Path) -> None:
    d = tmp_path / "docs"
    d.mkdir()
    (d / "a.md").write_text("# T\n\nHello 世界\n", encoding="utf-8")
    (d / "b.txt").write_text("one two", encoding="utf-8")
    r = op_document_words(
        {"root": str(d), "glob": "**/*.md", "max_files": 50}
    )
    assert r["ok"] is True
    assert r["total_files"] == 1
    assert r["total_chars"] > 0
    assert r.get("per_file") and r["per_file"][0].get("path") == "a.md"


def test_document_words_paths_mode(tmp_path: Path) -> None:
    p = tmp_path / "single.md"
    p.write_text("foo bar\nbaz\n", encoding="utf-8")
    r = op_document_words({"paths": [str(p)]})
    assert r["ok"] is True
    assert r["mode"] == "paths"
    assert r["total_files"] == 1
    assert r["total_lines"] == 2


def test_run_operation_aliases() -> None:
    r = run_operation("lines", {})
    assert r.get("ok") is False
    assert "root" in str(r.get("error", "")).lower() or r.get("error")

