"""Tests for TEST009 (playwright-wait-for-timeout)."""

import pytest
from pathlib import Path

from stablestack.checkers.testing.playwright_wait_for_timeout2 import PlaywrightWaitForTimeoutChecker


@pytest.fixture
def spec_file(tmp_path: Path):
    def _create(content: str, name: str = "login.spec.ts") -> Path:
        p = tmp_path / name
        p.write_text(content)
        return p
    return _create


@pytest.fixture
def e2e_file(tmp_path: Path):
    def _create(content: str, name: str = "checkout.ts") -> Path:
        e2e_dir = tmp_path / "e2e"
        e2e_dir.mkdir(exist_ok=True)
        p = e2e_dir / name
        p.write_text(content)
        return p
    return _create


class TestPlaywrightWaitForTimeout:
    @pytest.fixture
    def checker(self):
        return PlaywrightWaitForTimeoutChecker()

    # --- Detection ---

    def test_detects_waitForTimeout(self, checker, spec_file):
        code = """\
test('loads page', async ({ page }) => {
  await page.goto('/');
  await page.waitForTimeout(2000);
  await expect(page.locator('h1')).toBeVisible();
});
"""
        findings = checker.check_file(spec_file(code), code)
        assert len(findings) == 1
        assert findings[0].rule_id == "TEST009"

    def test_detects_bare_waitForTimeout(self, checker, spec_file):
        code = """\
test('waits', async ({ page }) => {
  await page.waitForTimeout(500);
});
"""
        findings = checker.check_file(spec_file(code), code)
        assert len(findings) == 1

    def test_detects_setTimeout_promise(self, checker, spec_file):
        code = """\
test('delays', async ({ page }) => {
  await new Promise(resolve => setTimeout(resolve, 1000));
  await expect(page).toHaveURL('/dashboard');
});
"""
        findings = checker.check_file(spec_file(code), code)
        assert len(findings) == 1

    def test_detects_multiple_waits(self, checker, spec_file):
        code = """\
test('multi wait', async ({ page }) => {
  await page.waitForTimeout(1000);
  await page.click('.btn');
  await page.waitForTimeout(500);
});
"""
        findings = checker.check_file(spec_file(code), code)
        assert len(findings) == 2

    def test_detects_in_test_tsx(self, checker, tmp_path):
        code = "await page.waitForTimeout(1000);"
        p = tmp_path / "dialog.test.tsx"
        p.write_text(code)
        findings = checker.check_file(p, code)
        assert len(findings) == 1

    def test_detects_in_e2e_dir(self, checker, e2e_file):
        code = "await page.waitForTimeout(3000);"
        findings = checker.check_file(e2e_file(code), code)
        assert len(findings) == 1

    # --- Suppression ---

    def test_no_flag_in_non_test_file(self, checker, tmp_path):
        """Should NOT flag waitForTimeout in production code."""
        code = "await page.waitForTimeout(1000);"
        p = tmp_path / "utils.ts"
        p.write_text(code)
        findings = checker.check_file(p, code)
        assert len(findings) == 0

    def test_skips_comments(self, checker, spec_file):
        code = """\
test('ok', async ({ page }) => {
  // await page.waitForTimeout(1000);
  await expect(page).toHaveURL('/');
});
"""
        findings = checker.check_file(spec_file(code), code)
        assert len(findings) == 0

    # --- Edge cases ---

    def test_empty_file(self, checker, spec_file):
        findings = checker.check_file(spec_file(""), "")
        assert len(findings) == 0

    def test_waitForSelector_not_flagged(self, checker, spec_file):
        code = """\
test('ok', async ({ page }) => {
  await page.waitForSelector('.loaded');
});
"""
        findings = checker.check_file(spec_file(code), code)
        assert len(findings) == 0

    def test_spec_js_detected(self, checker, tmp_path):
        code = "await page.waitForTimeout(500);"
        p = tmp_path / "nav.spec.js"
        p.write_text(code)
        findings = checker.check_file(p, code)
        assert len(findings) == 1
