from __future__ import annotations

import shutil
from pathlib import Path
from typing import Iterable

from zsc.cli import init


def _assert_paths_exist(base: Path, paths: Iterable[str]) -> None:
    for rel in paths:
        assert (base / rel).exists(), f"Expected path to exist: {rel}"


def test_init_creates_structure_in_empty_project(tmp_path: Path) -> None:
    base = tmp_path

    # Precondition: no special directories
    assert not (base / ".agents").exists()
    assert not (base / ".cursor").exists()
    assert not (base / ".codex").exists()
    assert not (base / ".claudecode").exists()

    init(str(base), None)

    _assert_paths_exist(
        base,
        [
            ".agents",
            ".agents/tasks",
            ".cursor/skills/zsc-help/SKILL.md",
            ".cursor/skills/zsc-create-task/SKILL.md",
            ".cursor/skills/zsc-task-list/SKILL.md",
            ".cursor/skills/zsc-task-status/SKILL.md",
            ".codex/skills/zsc-help/SKILL.md",
            ".codex/skills/zsc-create-task/SKILL.md",
            ".codex/skills/zsc-task-list/SKILL.md",
            ".codex/skills/zsc-task-status/SKILL.md",
            ".claudecode/skills/zsc-help/SKILL.md",
            ".claudecode/skills/zsc-create-task/SKILL.md",
            ".claudecode/skills/zsc-task-list/SKILL.md",
            ".claudecode/skills/zsc-task-status/SKILL.md",
        ],
    )


def test_init_is_idempotent(tmp_path: Path) -> None:
    base = tmp_path

    init(str(base), None)
    # Run again; should not raise and should keep existing files
    init(str(base), None)

    _assert_paths_exist(
        base,
        [
            ".agents",
            ".agents/tasks",
            ".cursor/skills/zsc-help/SKILL.md",
            ".cursor/skills/zsc-create-task/SKILL.md",
            ".cursor/skills/zsc-task-list/SKILL.md",
            ".cursor/skills/zsc-task-status/SKILL.md",
            ".codex/skills/zsc-help/SKILL.md",
            ".codex/skills/zsc-create-task/SKILL.md",
            ".codex/skills/zsc-task-list/SKILL.md",
            ".codex/skills/zsc-task-status/SKILL.md",
            ".claudecode/skills/zsc-help/SKILL.md",
            ".claudecode/skills/zsc-create-task/SKILL.md",
            ".claudecode/skills/zsc-task-list/SKILL.md",
            ".claudecode/skills/zsc-task-status/SKILL.md",
        ],
    )


def test_init_lang_option_persists(tmp_path: Path) -> None:
    """Non-interactive: --lang zh or --lang en writes .agents/zsc-lang and is used."""
    base = tmp_path
    assert not (base / ".agents").exists()

    init(str(base), "zh")
    assert (base / ".agents" / "zsc-lang").exists()
    assert (base / ".agents" / "zsc-lang").read_text(encoding="utf-8").strip() == "zh"

    # Re-init with en in a fresh .agents (simulate another project); here we test --lang en
    shutil.rmtree(base / ".agents")
    init(str(base), "en")
    assert (base / ".agents" / "zsc-lang").read_text(encoding="utf-8").strip() == "en"


def test_init_overwrites_existing_skill_files(tmp_path: Path) -> None:
    base = tmp_path

    # Manually create one existing SKILL.md; init should overwrite it with the chosen-language template
    cursor_skill = base / ".cursor" / "skills" / "zsc-create-task"
    cursor_skill.mkdir(parents=True, exist_ok=True)
    existing = cursor_skill / "SKILL.md"
    existing.write_text("custom skill content", encoding="utf-8")

    init(str(base), "en")

    # Existing file should be overwritten with the template (English)
    content = existing.read_text(encoding="utf-8")
    assert "custom skill content" not in content
    assert "zsc-create-task" in content

