import json
from pathlib import Path

import pytest

from pygitweb.config import Settings
from pygitweb.settings_config import init_settings, settings_batch_update, write_settings_file


@pytest.fixture
def settings_path(tmp_path: Path, monkeypatch: pytest.MonkeyPatch) -> Path:
	path = tmp_path / "settings.json"
	monkeypatch.setenv("PYGITWEB_SETTINGS_CONFIG", str(path))
	monkeypatch.setenv("PYGITWEB_AUTH", "0")
	return path


def test_creates_settings_file_from_environment(settings_path: Path, monkeypatch: pytest.MonkeyPatch) -> None:
	monkeypatch.setenv("PYGITWEB_SITE_NAME", "FromEnv")
	settings = init_settings()
	assert settings_path.is_file()
	data = json.loads(settings_path.read_text(encoding="utf-8"))
	assert data["SITE_NAME"] == "FromEnv"
	assert settings.SITE_NAME == "FromEnv"


def test_loads_existing_settings_file(settings_path: Path, monkeypatch: pytest.MonkeyPatch) -> None:
	settings_path.write_text(
		json.dumps({
			"PROJECTROOT": "/var/git",
			"PROJECTS_LIST": "/var/git",
			"PROJECT_MAXDEPTH": 2,
			"SITE_NAME": "FromFile",
			"EXPORT_OK": "",
			"LIST_ALL": True,
			"STRICT_EXPORT": False,
			"GIT": "git",
			"MAXLOAD": None,
			"AUTH": False,
			"AUTH_CONFIG": "",
			"SETTINGS_CONFIG": "",
		})
		+ "\n",
		encoding="utf-8",
	)
	monkeypatch.delenv("PYGITWEB_SITE_NAME", raising=False)
	settings = init_settings()
	assert settings.SITE_NAME == "FromFile"
	assert settings.PROJECT_MAXDEPTH == 2


def test_env_overrides_settings_file(settings_path: Path, monkeypatch: pytest.MonkeyPatch, capsys) -> None:
	settings_path.write_text(
		json.dumps({
			"PROJECTROOT": "/var/git",
			"PROJECTS_LIST": "/var/git",
			"PROJECT_MAXDEPTH": 1,
			"SITE_NAME": "FromFile",
			"EXPORT_OK": "",
			"LIST_ALL": True,
			"STRICT_EXPORT": False,
			"GIT": "git",
			"MAXLOAD": None,
			"AUTH": False,
			"AUTH_CONFIG": "",
			"SETTINGS_CONFIG": "",
		})
		+ "\n",
		encoding="utf-8",
	)
	monkeypatch.setenv("PYGITWEB_SITE_NAME", "FromEnv")
	settings = init_settings()
	assert settings.SITE_NAME == "FromEnv"
	assert json.loads(settings_path.read_text(encoding="utf-8"))["SITE_NAME"] == "FromEnv"
	err = capsys.readouterr().err
	assert "environment overrides settings file" in err
	assert "SITE_NAME" in err


def test_setattr_persists_to_file(settings_path: Path) -> None:
	settings = init_settings()
	settings.SITE_NAME = "Updated"
	assert json.loads(settings_path.read_text(encoding="utf-8"))["SITE_NAME"] == "Updated"


def test_batch_update_persists_once(settings_path: Path) -> None:
	settings = init_settings()
	with settings_batch_update(settings):
		settings.SITE_NAME = "BatchOne"
		settings.GIT = "/usr/bin/git"
	data = json.loads(settings_path.read_text(encoding="utf-8"))
	assert data["SITE_NAME"] == "BatchOne"
	assert data["GIT"] == "/usr/bin/git"


def test_write_settings_file_roundtrip(settings_path: Path) -> None:
	settings = Settings(AUTH=False, SITE_NAME="Roundtrip")
	write_settings_file(settings, settings_path)
	loaded = Settings.model_validate_json(settings_path.read_text(encoding="utf-8"))
	assert loaded.SITE_NAME == "Roundtrip"
	assert loaded.AUTH is False