"""Unit tests for config file loader."""

from __future__ import annotations

import pytest

from extractor.config import _interpolate, load_config


def test_load_config_empty_when_no_file(tmp_path):
    cfg = load_config(tmp_path / "nonexistent.toml")
    assert cfg == {}


def test_load_config_auto_search_not_found(tmp_path, monkeypatch):
    monkeypatch.chdir(tmp_path)
    cfg = load_config()
    assert cfg == {}


def test_interpolate_replaces_env_var(monkeypatch):
    monkeypatch.setenv("MY_TEST_VAR", "hello")
    result = _interpolate("prefix_${MY_TEST_VAR}_suffix")
    assert result == "prefix_hello_suffix"


def test_interpolate_no_vars_unchanged():
    result = _interpolate("no variables here")
    assert result == "no variables here"


def test_interpolate_raises_on_missing_var():
    with pytest.raises(KeyError, match="UNDEFINED_VAR_XYZ"):
        _interpolate("${UNDEFINED_VAR_XYZ}")


def test_interpolate_multiple_vars(monkeypatch):
    monkeypatch.setenv("HOST", "localhost")
    monkeypatch.setenv("PORT", "5432")
    result = _interpolate("postgres://${HOST}:${PORT}/db")
    assert result == "postgres://localhost:5432/db"


def test_load_config_reads_toml(tmp_path):
    config_file = tmp_path / "extractor.toml"
    config_file.write_text('[run]\nchunk_size = 1024\nmode = "chunks"\n\n[sink]\ntype = "qdrant"\n')
    cfg = load_config(config_file)
    assert cfg["run"]["chunk_size"] == 1024
    assert cfg["run"]["mode"] == "chunks"
    assert cfg["sink"]["type"] == "qdrant"


def test_load_config_interpolates_env_vars(tmp_path, monkeypatch):
    monkeypatch.setenv("TEST_SINK_URI", "http://qdrant:6333")
    config_file = tmp_path / "extractor.toml"
    config_file.write_text('[sink]\nuri = "${TEST_SINK_URI}"\n')
    cfg = load_config(config_file)
    assert cfg["sink"]["uri"] == "http://qdrant:6333"


def test_load_config_auto_finds_extractor_toml(tmp_path, monkeypatch):
    monkeypatch.chdir(tmp_path)
    (tmp_path / "extractor.toml").write_text("[run]\nchunk_size = 2048\n")
    cfg = load_config()
    assert cfg["run"]["chunk_size"] == 2048


def test_load_config_auto_finds_dot_extractor_toml(tmp_path, monkeypatch):
    monkeypatch.chdir(tmp_path)
    (tmp_path / ".extractor.toml").write_text("[run]\nchunk_size = 512\n")
    cfg = load_config()
    assert cfg["run"]["chunk_size"] == 512


def test_load_config_extractor_toml_takes_priority(tmp_path, monkeypatch):
    """extractor.toml is checked before .extractor.toml."""
    monkeypatch.chdir(tmp_path)
    (tmp_path / "extractor.toml").write_text("[run]\nchunk_size = 999\n")
    (tmp_path / ".extractor.toml").write_text("[run]\nchunk_size = 111\n")
    cfg = load_config()
    assert cfg["run"]["chunk_size"] == 999


def test_load_config_explicit_path_overrides_cwd(tmp_path, monkeypatch):
    """Explicit path arg bypasses auto-search."""
    monkeypatch.chdir(tmp_path)
    (tmp_path / "extractor.toml").write_text("[run]\nchunk_size = 111\n")
    explicit = tmp_path / "other.toml"
    explicit.write_text("[run]\nchunk_size = 777\n")
    cfg = load_config(explicit)
    assert cfg["run"]["chunk_size"] == 777


def test_load_config_nested_interpolation(tmp_path, monkeypatch):
    """Env var substitution works inside nested TOML tables."""
    monkeypatch.setenv("MY_DB_NAME", "mydb")
    config_file = tmp_path / "extractor.toml"
    config_file.write_text('[database]\nname = "${MY_DB_NAME}"\n')
    cfg = load_config(config_file)
    assert cfg["database"]["name"] == "mydb"


def test_load_config_list_values(tmp_path):
    config_file = tmp_path / "extractor.toml"
    config_file.write_text(
        '[run]\nexclude_types = ["structural:page_header", "structural:page_footer"]\n'
    )
    cfg = load_config(config_file)
    assert cfg["run"]["exclude_types"] == ["structural:page_header", "structural:page_footer"]
