"""Tests for pulse config module."""

import json
import os
import tempfile

import pytest

from pulse.config import load_config, parse_yaml, validate_config


class TestParseYaml:
    def test_simple_mapping(self):
        result = parse_yaml("key: value\nother: 123")
        assert result["key"] == "value"
        assert result["other"] == 123

    def test_nested_list(self):
        yaml_text = """\
vitals:
  - name: "Test"
    checks:
      - type: file_freshness
        path: "data.json"
        max_age: "2h"
"""
        result = parse_yaml(yaml_text)
        assert "vitals" in result
        assert len(result["vitals"]) == 1
        assert result["vitals"][0]["name"] == "Test"
        checks = result["vitals"][0]["checks"]
        assert len(checks) == 1
        assert checks[0]["type"] == "file_freshness"

    def test_boolean_values(self):
        result = parse_yaml("enabled: true\ndisabled: false")
        assert result["enabled"] is True
        assert result["disabled"] is False

    def test_quoted_strings(self):
        result = parse_yaml('name: "hello world"')
        assert result["name"] == "hello world"

    def test_comments_ignored(self):
        result = parse_yaml("# comment\nkey: value")
        assert result["key"] == "value"


class TestValidateConfig:
    def test_valid_config(self):
        config = {
            "vitals": [
                {
                    "name": "Test",
                    "checks": [
                        {"type": "file_freshness", "path": "x.json", "max_age": "1h"}
                    ],
                }
            ]
        }
        errors = validate_config(config)
        assert errors == []

    def test_missing_vitals(self):
        errors = validate_config({})
        assert len(errors) == 1
        assert "Missing 'vitals'" in errors[0]

    def test_missing_name(self):
        config = {"vitals": [{"checks": []}]}
        errors = validate_config(config)
        assert any("missing 'name'" in e for e in errors)

    def test_unknown_type(self):
        config = {
            "vitals": [
                {"name": "X", "checks": [{"type": "bogus"}]}
            ]
        }
        errors = validate_config(config)
        assert any("unknown type" in e for e in errors)

    def test_missing_path_for_file_freshness(self):
        config = {
            "vitals": [
                {"name": "X", "checks": [{"type": "file_freshness", "max_age": "1h"}]}
            ]
        }
        errors = validate_config(config)
        assert any("missing 'path'" in e for e in errors)

    def test_json_key_changed_missing_key(self):
        config = {
            "vitals": [
                {"name": "X", "checks": [{"type": "json_key_changed", "path": "x", "max_age": "1h"}]}
            ]
        }
        errors = validate_config(config)
        assert any("missing 'key'" in e for e in errors)

    def test_process_output_valid(self):
        config = {
            "vitals": [
                {"name": "X", "checks": [{"type": "process_output", "command": "echo hi"}]}
            ]
        }
        errors = validate_config(config)
        assert errors == []


class TestLoadConfig:
    def test_load_json(self, tmp_path, monkeypatch):
        config = {"vitals": [{"name": "T", "checks": []}]}
        (tmp_path / "pulse.json").write_text(json.dumps(config))
        monkeypatch.chdir(tmp_path)
        result = load_config()
        assert result["vitals"][0]["name"] == "T"

    def test_load_explicit_path(self, tmp_path):
        config = {"vitals": [{"name": "X", "checks": []}]}
        p = tmp_path / "custom.json"
        p.write_text(json.dumps(config))
        result = load_config(str(p))
        assert result["vitals"][0]["name"] == "X"

    def test_not_found(self, tmp_path, monkeypatch):
        monkeypatch.chdir(tmp_path)
        with pytest.raises(FileNotFoundError):
            load_config()
