import json

import pytest

from app.core.app_settings import (
    _coerce_value,
    apply_settings_to_app,
    bootstrap_settings,
    env_locks,
    get_settings_payload,
    write_settings,
)


def test_write_and_bootstrap_settings(tmp_path, monkeypatch):
    settings_file = tmp_path / "compton_settings.json"
    monkeypatch.setattr("app.core.app_settings.settings.compton_settings_path", str(settings_file))
    monkeypatch.delenv("ENABLE_DOCS", raising=False)

    merged = write_settings({"enable_docs": False, "log_level": "INFO"})
    assert merged["enable_docs"] is False
    assert settings_file.exists()

    bootstrap_settings()
    from app.core.config import settings

    assert settings.enable_docs is False


def test_env_locks_skip_locked_keys(tmp_path, monkeypatch):
    settings_file = tmp_path / "compton_settings.json"
    monkeypatch.setattr("app.core.app_settings.settings.compton_settings_path", str(settings_file))
    monkeypatch.setenv("ENABLE_DOCS", "true")
    monkeypatch.setattr("app.core.app_settings.settings.enable_docs", True)

    write_settings({"enable_docs": False})
    payload = get_settings_payload()
    assert payload["locks"]["enable_docs"] is True
    assert payload["values"]["enable_docs"] is True


def test_apply_settings_coerces_list_and_bool(monkeypatch):
    apply_settings_to_app({"enable_docs": "false", "cors_origins": "http://a.test,http://b.test"})
    from app.core.config import settings

    assert settings.enable_docs is False
    assert settings.cors_origins == ["http://a.test", "http://b.test"]
    assert isinstance(env_locks(), dict)


def test_read_settings_ignores_invalid_payload(tmp_path, monkeypatch):
    settings_file = tmp_path / "compton_settings.json"
    settings_file.write_text("[]", encoding="utf-8")
    monkeypatch.setattr("app.core.app_settings.settings.compton_settings_path", str(settings_file))
    from app.core.app_settings import read_settings

    assert read_settings() == {}


def test_coerce_value_rejects_invalid_list():
    with pytest.raises(ValueError, match="INVALID_LIST_cors_origins"):
        _coerce_value("cors_origins", 123)

