from __future__ import annotations

import json
import logging
from pathlib import Path
import warnings

import pytest

from azure_functions_logging._host_config import warn_host_json_level_conflict


def _write_host_json(path: Path, content: dict[str, object]) -> None:
    path.write_text(json.dumps(content), encoding="utf-8")


def test_warns_when_host_level_is_more_restrictive(
    tmp_path: Path,
    monkeypatch: pytest.MonkeyPatch,
) -> None:
    _write_host_json(
        tmp_path / "host.json",
        {"logging": {"logLevel": {"default": "Warning"}}},
    )
    monkeypatch.chdir(tmp_path)

    with pytest.warns(UserWarning, match="more restrictive") as warning_list:
        warn_host_json_level_conflict(logging.INFO)

    message = str(warning_list[0].message)
    assert "'Warning'" in message
    assert "'INFO'" in message


def test_no_warning_when_host_level_is_less_restrictive(
    tmp_path: Path,
    monkeypatch: pytest.MonkeyPatch,
) -> None:
    _write_host_json(
        tmp_path / "host.json",
        {"logging": {"logLevel": {"default": "Information"}}},
    )
    monkeypatch.chdir(tmp_path)

    with warnings.catch_warnings(record=True) as warning_list:
        warnings.simplefilter("always")
        warn_host_json_level_conflict(logging.WARNING)

    assert len(warning_list) == 0


def test_no_warning_when_host_json_does_not_exist(
    tmp_path: Path,
    monkeypatch: pytest.MonkeyPatch,
) -> None:
    monkeypatch.chdir(tmp_path)

    with warnings.catch_warnings(record=True) as warning_list:
        warnings.simplefilter("always")
        warn_host_json_level_conflict(logging.INFO)

    assert len(warning_list) == 0


def test_no_warning_when_logging_config_is_missing(
    tmp_path: Path,
    monkeypatch: pytest.MonkeyPatch,
) -> None:
    _write_host_json(tmp_path / "host.json", {"version": "2.0"})
    monkeypatch.chdir(tmp_path)

    with warnings.catch_warnings(record=True) as warning_list:
        warnings.simplefilter("always")
        warn_host_json_level_conflict(logging.INFO)

    assert len(warning_list) == 0


def test_warns_when_host_level_is_none_disables_all_logging(
    tmp_path: Path,
    monkeypatch: pytest.MonkeyPatch,
) -> None:
    """logLevel.default = 'None' disables all logging — should always warn."""
    _write_host_json(
        tmp_path / "host.json",
        {"logging": {"logLevel": {"default": "None"}}},
    )
    monkeypatch.chdir(tmp_path)

    with pytest.warns(UserWarning, match="more restrictive") as warning_list:
        warn_host_json_level_conflict(logging.DEBUG)

    message = str(warning_list[0].message)
    assert "'None'" in message


def test_no_warning_when_host_json_is_malformed(
    tmp_path: Path,
    monkeypatch: pytest.MonkeyPatch,
) -> None:
    """Lines 29-30: invalid JSON in host.json is silently ignored."""
    (tmp_path / "host.json").write_text("not valid json", encoding="utf-8")
    monkeypatch.chdir(tmp_path)

    with warnings.catch_warnings(record=True) as warning_list:
        warnings.simplefilter("always")
        warn_host_json_level_conflict(logging.INFO)

    assert len(warning_list) == 0


def test_no_warning_when_log_level_value_is_not_a_string(
    tmp_path: Path,
    monkeypatch: pytest.MonkeyPatch,
) -> None:
    """Line 38: logLevel.default is not a str (e.g. an integer) -> silently ignored."""
    _write_host_json(
        tmp_path / "host.json",
        {"logging": {"logLevel": {"default": 42}}},
    )
    monkeypatch.chdir(tmp_path)

    with warnings.catch_warnings(record=True) as warning_list:
        warnings.simplefilter("always")
        warn_host_json_level_conflict(logging.DEBUG)

    assert len(warning_list) == 0


def test_no_warning_when_host_level_is_unrecognized_string(
    tmp_path: Path,
    monkeypatch: pytest.MonkeyPatch,
) -> None:
    """Line 42: logLevel.default is a string not in _HOST_LEVEL_TO_LOGGING -> silently ignored."""
    _write_host_json(
        tmp_path / "host.json",
        {"logging": {"logLevel": {"default": "SuperVerbose"}}},
    )
    monkeypatch.chdir(tmp_path)

    with warnings.catch_warnings(record=True) as warning_list:
        warnings.simplefilter("always")
        warn_host_json_level_conflict(logging.DEBUG)

    assert len(warning_list) == 0
