"""Unit tests for scad_lint tool."""

import pytest

import navi.tools.scad_lint as scad_lint_mod
from navi.tools.base import current_session_id
from navi.tools.scad_lint import ScadLintTool, lint_scad_source


def test_lint_detects_draft_language_unknown_identifier_and_abandoned_module():
    source = """
module unused() {
  cube([1, 1, 1]);
}

// Actually, let's use a corrected implementation.
module final_model() {
  cube([pad_recss_width, 2, 3]);
}

final_model();
"""

    errors, warnings = lint_scad_source(source)

    assert any("draft/self-correction" in item for item in errors)
    assert any("pad_recss_width" in item for item in errors)
    assert any("unused" in item for item in warnings)


def test_lint_detects_hole_diameter_division_warning():
    source = """
hole_diameter = 3.2;
cylinder(d = hole_diameter / 2, h = 5);
"""

    errors, warnings = lint_scad_source(source)

    assert errors == []
    assert any("hole_diameter / 2" in item for item in warnings)


class TestScadLintTool:
    @pytest.fixture
    def tool(self, monkeypatch, tmp_path):
        monkeypatch.setattr(scad_lint_mod.settings, "session_files_dir", str(tmp_path / "sessions"))
        token = current_session_id.set("sess-1")
        try:
            yield ScadLintTool()
        finally:
            current_session_id.reset(token)

    async def test_resolves_simple_filename_inside_session_dir(self, tool, tmp_path):
        sess_dir = tmp_path / "sessions" / "sess-1"
        sess_dir.mkdir(parents=True)
        (sess_dir / "ok.scad").write_text("cube([1, 1, 1]);")

        result = await tool.execute({"path": "ok.scad"})

        assert result.success
        assert "OK" in result.output

    async def test_rejects_wrong_session_dir(self, tool, tmp_path):
        other_dir = tmp_path / "sessions" / "sess-2"
        other_dir.mkdir(parents=True)
        other = other_dir / "model.scad"
        other.write_text("cube([1, 1, 1]);")

        result = await tool.execute({"path": str(other)})

        assert not result.success
        assert result.error == "wrong_session_dir"

    async def test_strict_fails_on_warnings(self, tool, tmp_path):
        sess_dir = tmp_path / "sessions" / "sess-1"
        sess_dir.mkdir(parents=True)
        (sess_dir / "warn.scad").write_text("hole_diameter = 3.2; cylinder(d=hole_diameter/2, h=5);")

        result = await tool.execute({"path": "warn.scad", "strict": True})

        assert not result.success
        assert result.error == "scad_lint_failed"
