from __future__ import annotations

from typing import TYPE_CHECKING

if TYPE_CHECKING:
    from pathlib import Path

    from tox.pytest import ToxProjectCreator


def out_no_src(path: Path) -> str:
    return (
        f"ROOT: No loadable tox.ini or setup.cfg or pyproject.toml or tox.toml found, assuming empty tox.ini at {path}"
        f"\ndefault environments:\npy -> [no description]\n"
    )


def test_no_src_cwd(tox_project: ToxProjectCreator) -> None:
    project = tox_project({})
    outcome = project.run("l")
    outcome.assert_success()
    assert outcome.out == out_no_src(project.path)
    assert outcome.state.conf.src_path == (project.path / "tox.ini")


def test_no_src_has_py_project_toml_above(tox_project: ToxProjectCreator, tmp_path: Path) -> None:
    (tmp_path / "pyproject.toml").write_text("")
    project = tox_project({})
    outcome = project.run("l")
    outcome.assert_success()
    assert outcome.out == out_no_src(tmp_path)
    assert outcome.state.conf.src_path == (tmp_path / "tox.ini")


def test_no_src_root_dir(tox_project: ToxProjectCreator, tmp_path: Path) -> None:
    root = tmp_path / "root"
    root.mkdir()
    project = tox_project({})
    outcome = project.run("l", "--root", str(root))
    outcome.assert_success()
    assert outcome.out == out_no_src(root)
    assert outcome.state.conf.src_path == (root / "tox.ini")


def test_bad_src_content(tox_project: ToxProjectCreator, tmp_path: Path) -> None:
    project = tox_project({})

    outcome = project.run("l", "-c", str(tmp_path / "setup.cfg"))
    outcome.assert_failed()
    assert outcome.out == f"ROOT: HandledError| config file {tmp_path / 'setup.cfg'} does not exist\n"


def test_malformed_config_does_not_prevent_help(tox_project: ToxProjectCreator) -> None:
    project = tox_project({"tox.toml": "deps =\n    mypy\n"})
    outcome = project.run("--help")
    outcome.assert_success()
    assert "usage: tox" in outcome.out


def test_malformed_toml_in_dir_reports_error(tox_project: ToxProjectCreator) -> None:
    """Config discovery in a directory should report TOML parse errors instead of silently ignoring them."""
    project = tox_project({})
    # Write a pyproject.toml with an invalid TOML escape sequence (unescaped backslash)
    (project.path / "pyproject.toml").write_text('[tool.tox]\ntest = "c:\\path"\n', encoding="utf-8")
    outcome = project.run("l", "-c", str(project.path))
    outcome.assert_failed()
    assert "failed loading" in outcome.out


def test_toml_native_preferred_over_legacy_tox_ini(tox_project: ToxProjectCreator) -> None:
    """When pyproject.toml has both legacy_tox_ini and native TOML config, native TOML should win."""
    pyproject = """\
[tool.tox]
legacy_tox_ini = \"\"\"
[tox]
min_version = 4.21
[testenv]
commands = python -c "print('legacy')"
\"\"\"
env_list = ["native"]

[tool.tox.env_run_base]
package = "skip"
commands = [["python", "-c", "print('native')"]]
"""
    project = tox_project({"pyproject.toml": pyproject})
    outcome = project.run("l")
    outcome.assert_success()
    assert "native" in outcome.out
    assert "legacy" not in outcome.out
