import pytest

from typing import Any

from frisk_sdk.redact.redaction_options import (
    RedactionOptionsDict,
    RedactionOptions,
    normalize_redaction_options,
)


def test_normalize_frisk_options_none_returns_defaults():
    assert normalize_redaction_options(None) == {
        "redact_tool_args": None,
        "redact_agent_state": None,
    }


def test_normalize_frisk_options_default_arg_returns_defaults():
    # Ensure the default parameter behaves like passing None explicitly.
    assert normalize_redaction_options() == {
        "redact_tool_args": None,
        "redact_agent_state": None,
    }


def test_normalize_frisk_options_dict_partial_merges_with_defaults():
    inp: RedactionOptionsDict = {"redact_tool_args": True}
    assert normalize_redaction_options(inp) == {
        "redact_tool_args": True,
        "redact_agent_state": None,
    }


def test_normalize_frisk_options_dict_allows_redact_lists():
    inp: RedactionOptionsDict = {"redact_agent_state": ["user.ssn", "api_key"]}
    assert normalize_redaction_options(inp) == {
        "redact_tool_args": None,
        "redact_agent_state": ["user.ssn", "api_key"],
    }


def test_normalize_frisk_options_dict_empty_returns_defaults():
    inp: RedactionOptionsDict = {}
    assert normalize_redaction_options(inp) == {
        "redact_tool_args": None,
        "redact_agent_state": None,
    }


def test_normalize_frisk_options_dataclass_converts_to_dict():
    opts = RedactionOptions(redact_tool_args=False, redact_agent_state=["foo"])
    assert normalize_redaction_options(opts) == {
        "redact_tool_args": False,
        "redact_agent_state": ["foo"],
    }


def test_normalize_frisk_options_dataclass_defaults_to_none_fields():
    # Dataclass path should preserve the dataclass fields (both None by default)
    # and match the same shape as the dict defaults.
    opts = RedactionOptions()
    assert normalize_redaction_options(opts) == {
        "redact_tool_args": None,
        "redact_agent_state": None,
    }


def test_normalize_frisk_options_rejects_non_mapping_non_dataclass():
    # Anything that's not None, not a dataclass, and not mapping-like should fail.
    bad: Any = 123
    with pytest.raises(TypeError):
        normalize_redaction_options(bad)
