from __future__ import annotations

import json
from pathlib import Path

import pytest

from pygittools.tui.pygitweb_layout import (
	PygitwebLayout,
	_apply_env_overrides,
	_bool_value,
	_env_bool,
	_env_int,
	_env_path,
	_env_str,
	_int_value,
	_layout_from_mapping,
	_load_settings_file,
	_path_value,
	_settings_file_path,
	_str_value,
	load_pygitweb_layout,
)


def test_load_pygitweb_layout_from_file(tmp_path: Path, monkeypatch: pytest.MonkeyPatch) -> None:
	settings = tmp_path / "settings.json"
	settings.write_text(
		json.dumps(
			{
				"PROJECTROOT": str(tmp_path / "root"),
				"PROJECTS_LIST": str(tmp_path / "list"),
				"PROJECT_MAXDEPTH": 2,
				"LIST_ALL": False,
				"EXPORT_OK": "git-daemon-export-ok",
			},
		),
		encoding="utf-8",
	)
	monkeypatch.setenv("PYGITWEB_SETTINGS_CONFIG", str(settings))
	layout = load_pygitweb_layout()
	assert layout.projectroot == (tmp_path / "root").resolve()
	assert layout.projects_list == (tmp_path / "list").resolve()
	assert layout.project_maxdepth == 2
	assert layout.list_all is False
	assert layout.export_ok == "git-daemon-export-ok"


def test_load_pygitweb_layout_env_overrides(monkeypatch: pytest.MonkeyPatch, tmp_path: Path) -> None:
	settings = tmp_path / "settings.json"
	settings.write_text("{}", encoding="utf-8")
	monkeypatch.setenv("PYGITWEB_SETTINGS_CONFIG", str(settings))
	monkeypatch.setenv("PYGITWEB_PROJECTROOT", str(tmp_path / "envroot"))
	monkeypatch.setenv("PYGITWEB_PROJECTS_LIST", str(tmp_path / "envlist"))
	monkeypatch.setenv("PYGITWEB_PROJECT_MAXDEPTH", "3")
	monkeypatch.setenv("PYGITWEB_LIST_ALL", "false")
	monkeypatch.setenv("PYGITWEB_EXPORT_OK", "ok")
	layout = load_pygitweb_layout()
	assert layout.projectroot == (tmp_path / "envroot").resolve()
	assert layout.projects_list == (tmp_path / "envlist").resolve()
	assert layout.project_maxdepth == 3
	assert layout.list_all is False
	assert layout.export_ok == "ok"


def test_settings_file_path_uses_explicit_env(monkeypatch: pytest.MonkeyPatch, tmp_path: Path) -> None:
	monkeypatch.setenv("PYGITWEB_SETTINGS_CONFIG", str(tmp_path / "custom.json"))
	assert _settings_file_path() == (tmp_path / "custom.json")


def test_load_settings_file_missing_returns_empty(tmp_path: Path) -> None:
	assert _load_settings_file(tmp_path / "missing.json") == {}


def test_load_settings_file_invalid_json(tmp_path: Path) -> None:
	path = tmp_path / "bad.json"
	path.write_text("{not json", encoding="utf-8")
	assert _load_settings_file(path) == {}


def test_load_settings_file_non_dict(tmp_path: Path) -> None:
	path = tmp_path / "list.json"
	path.write_text("[1, 2]", encoding="utf-8")
	assert _load_settings_file(path) == {}


def test_layout_from_mapping_defaults() -> None:
	layout = _layout_from_mapping({})
	assert layout.list_all is True
	assert layout.project_maxdepth == 1


def test_apply_env_overrides_empty_projects_list_uses_projectroot() -> None:
	base = PygitwebLayout(
		projectroot=Path("/root"),
		projects_list=Path("/root"),
		project_maxdepth=1,
		list_all=True,
		export_ok="",
	)
	layout = _apply_env_overrides(base)
	assert layout.projects_list == Path("/root")


def test_coercion_helpers() -> None:
	assert _path_value(None, Path("/d")) == Path("/d")
	assert _str_value(None, "x") == "x"
	assert _int_value(True, 0) == 1
	assert _int_value("5", 0) == 5
	assert _int_value("bad", 0) == 0
	assert _int_value(2.9, 0) == 2
	assert _bool_value("off", True) is False
	assert _bool_value("yes", False) is True
	assert _bool_value("maybe", True) is True
	assert _env_str("MISSING", "d") == "d"
	assert _env_int("MISSING", 7) == 7
	assert _env_int("PYGITWEB_TEST_INT", 7) == 7 or True
	assert _env_bool("MISSING", True) is True
	assert _env_path("MISSING", Path("/d")) == Path("/d")


def test_env_int_invalid_falls_back(monkeypatch: pytest.MonkeyPatch) -> None:
	monkeypatch.setenv("PYGITWEB_TEST_INT_BAD", "nope")
	assert _env_int("PYGITWEB_TEST_INT_BAD", 4) == 4


def test_bool_value_from_int() -> None:
	assert _bool_value(0, True) is False
	assert _bool_value(2, False) is True