"""Tests for Settings / node_name fail-fast.

Regression coverage for the evt-unknown-* poison bug: a node_name of "unknown"
(or empty) produced event files that pinned the observer checkpoint and blocked
PIHA for ~34 days (see fix d5139c9). The agent must now refuse to start rather
than ever emit such a file.
"""
from __future__ import annotations

import os
from pathlib import Path

import pytest
from pydantic import ValidationError

from ha_diag import config
from ha_diag.config import Settings


@pytest.fixture(autouse=True)
def _isolate_environ():
    """Snapshot os.environ — Settings.load() mutates it via setdefault()."""
    saved = dict(os.environ)
    yield
    os.environ.clear()
    os.environ.update(saved)


# ---------------------------------------------------------------------------
# node_name loaded from env NODE_NAME
# ---------------------------------------------------------------------------


def test_node_name_from_env(monkeypatch):
    monkeypatch.setenv("NODE_NAME", "piha")
    settings = Settings()
    assert settings.node_name == "piha"


def test_node_name_from_env_case_insensitive_var(monkeypatch):
    # BaseSettings is case-insensitive: lowercase env var maps to the field too.
    monkeypatch.delenv("NODE_NAME", raising=False)
    monkeypatch.setenv("node_name", "chelsty-infra")
    settings = Settings()
    assert settings.node_name == "chelsty-infra"


def test_node_name_whitespace_is_stripped(monkeypatch):
    monkeypatch.setenv("NODE_NAME", "  piha  ")
    settings = Settings()
    assert settings.node_name == "piha"


# ---------------------------------------------------------------------------
# fail-fast: unknown / empty node_name refuses to start
# ---------------------------------------------------------------------------


def test_explicit_unknown_node_name_refuses(monkeypatch):
    monkeypatch.delenv("NODE_NAME", raising=False)
    with pytest.raises(ValidationError) as exc:
        Settings(node_name="unknown")
    assert "refusing to start" in str(exc.value)


def test_unknown_case_insensitive_refuses(monkeypatch):
    monkeypatch.delenv("NODE_NAME", raising=False)
    with pytest.raises(ValidationError):
        Settings(node_name="UNKNOWN")


def test_empty_node_name_refuses(monkeypatch):
    monkeypatch.delenv("NODE_NAME", raising=False)
    with pytest.raises(ValidationError):
        Settings(node_name="")


def test_whitespace_only_node_name_refuses(monkeypatch):
    monkeypatch.delenv("NODE_NAME", raising=False)
    with pytest.raises(ValidationError):
        Settings(node_name="   ")


def test_env_unknown_refuses(monkeypatch):
    monkeypatch.setenv("NODE_NAME", "unknown")
    with pytest.raises(ValidationError):
        Settings()


def test_default_without_env_refuses(monkeypatch):
    # No NODE_NAME anywhere → the "unknown" default must be rejected, not used.
    monkeypatch.delenv("NODE_NAME", raising=False)
    monkeypatch.delenv("node_name", raising=False)
    with pytest.raises(ValidationError):
        Settings()


# ---------------------------------------------------------------------------
# precedence: env wins over YAML for node_name
# ---------------------------------------------------------------------------


def test_env_wins_over_yaml(monkeypatch, tmp_path: Path):
    yaml_file = tmp_path / "ha-diag-agent.yaml"
    yaml_file.write_text("node_name: solaria\n")
    monkeypatch.setattr(config, "_CONFIG_YAML", yaml_file)
    monkeypatch.setenv("NODE_NAME", "piha")

    settings = Settings.load()
    # env value must win; YAML only supplies a default when env is absent.
    assert settings.node_name == "piha"


def test_yaml_supplies_node_name_when_env_absent(monkeypatch, tmp_path: Path):
    yaml_file = tmp_path / "ha-diag-agent.yaml"
    yaml_file.write_text("node_name: chelsty-infra\n")
    monkeypatch.setattr(config, "_CONFIG_YAML", yaml_file)
    monkeypatch.delenv("NODE_NAME", raising=False)
    monkeypatch.delenv("node_name", raising=False)

    settings = Settings.load()
    assert settings.node_name == "chelsty-infra"


def test_yaml_unknown_still_refuses(monkeypatch, tmp_path: Path):
    # Even if YAML carries the poison value, fail-fast must still fire.
    yaml_file = tmp_path / "ha-diag-agent.yaml"
    yaml_file.write_text("node_name: unknown\n")
    monkeypatch.setattr(config, "_CONFIG_YAML", yaml_file)
    monkeypatch.delenv("NODE_NAME", raising=False)
    monkeypatch.delenv("node_name", raising=False)

    with pytest.raises(ValidationError):
        Settings.load()


def test_load_valid_node_name(monkeypatch, tmp_path: Path):
    monkeypatch.setattr(config, "_CONFIG_YAML", tmp_path / "does-not-exist.yaml")
    monkeypatch.setenv("NODE_NAME", "piha")
    settings = Settings.load()
    assert settings.node_name == "piha"
