"""Unit tests for parsing utilities.

Tests for parse_dict_input and other parsing functions used by MCP tools
to handle flexible input formats from different clients.
"""

import pytest

from testio_mcp.utilities.parsing import parse_dict_input


class TestParseDictInput:
    """Tests for parse_dict_input function."""

    @pytest.mark.unit
    def test_returns_none_for_none_input(self) -> None:
        """None input returns None."""
        assert parse_dict_input(None) is None

    @pytest.mark.unit
    def test_returns_none_for_empty_string(self) -> None:
        """Empty string returns None."""
        assert parse_dict_input("") is None
        assert parse_dict_input("  ") is None

    @pytest.mark.unit
    def test_returns_none_for_empty_dict(self) -> None:
        """Empty dict returns None."""
        assert parse_dict_input({}) is None

    @pytest.mark.unit
    def test_returns_dict_for_dict_input(self) -> None:
        """Dict input is returned as-is."""
        result = parse_dict_input({"product_id": 598})
        assert result == {"product_id": 598}

    @pytest.mark.unit
    def test_returns_dict_for_nested_dict(self) -> None:
        """Nested dict is returned as-is."""
        input_dict = {"product_id": [598, 599], "status": ["running", "locked"]}
        result = parse_dict_input(input_dict)
        assert result == input_dict

    @pytest.mark.unit
    def test_parses_json_string_simple(self) -> None:
        """Simple JSON string is parsed to dict."""
        result = parse_dict_input('{"product_id": 598}')
        assert result == {"product_id": 598}

    @pytest.mark.unit
    def test_parses_json_string_with_array(self) -> None:
        """JSON string with array value is parsed correctly."""
        result = parse_dict_input('{"product_id": [598, 599]}')
        assert result == {"product_id": [598, 599]}

    @pytest.mark.unit
    def test_parses_json_string_complex(self) -> None:
        """Complex JSON string is parsed correctly."""
        result = parse_dict_input('{"product_id": [9547, 9548], "status": ["running"]}')
        assert result == {"product_id": [9547, 9548], "status": ["running"]}

    @pytest.mark.unit
    def test_parses_json_string_with_whitespace(self) -> None:
        """JSON string with leading/trailing whitespace is parsed."""
        result = parse_dict_input('  {"product_id": 598}  ')
        assert result == {"product_id": 598}

    @pytest.mark.unit
    def test_raises_for_invalid_json(self) -> None:
        """Invalid JSON raises ValueError."""
        with pytest.raises(ValueError) as exc_info:
            parse_dict_input('{"product_id": }')
        assert "Invalid JSON object format" in str(exc_info.value)

    @pytest.mark.unit
    def test_raises_for_json_array(self) -> None:
        """JSON array (not object) raises ValueError."""
        with pytest.raises(ValueError) as exc_info:
            parse_dict_input("[598, 599]")
        assert "JSON object" in str(exc_info.value)

    @pytest.mark.unit
    def test_raises_for_plain_string(self) -> None:
        """Plain string (not JSON) raises ValueError."""
        with pytest.raises(ValueError) as exc_info:
            parse_dict_input("product_id=598")
        assert "String input must be a JSON object" in str(exc_info.value)

    @pytest.mark.unit
    def test_raises_for_integer(self) -> None:
        """Integer input raises ValueError."""
        with pytest.raises(ValueError) as exc_info:
            parse_dict_input(598)  # type: ignore[arg-type]
        assert "Unsupported input type" in str(exc_info.value)

    @pytest.mark.unit
    def test_raises_for_list(self) -> None:
        """List input raises ValueError."""
        with pytest.raises(ValueError) as exc_info:
            parse_dict_input([598, 599])  # type: ignore[arg-type]
        assert "Unsupported input type" in str(exc_info.value)

    @pytest.mark.unit
    def test_returns_none_for_empty_json_object(self) -> None:
        """Empty JSON object string returns None."""
        assert parse_dict_input("{}") is None

    @pytest.mark.unit
    def test_actual_frontend_error_case(self) -> None:
        """Test the actual error case from the frontend agent.

        This is the exact format that was causing the validation error:
        Input should be a valid dictionary [type=dict_type,
        input_value='{"product_id":[9547,9548]}', input_type=str]
        """
        # This is the exact input that was failing
        result = parse_dict_input('{"product_id":[9547,9548]}')
        assert result == {"product_id": [9547, 9548]}

    @pytest.mark.unit
    def test_single_product_id_as_string(self) -> None:
        """Test single product_id in JSON string format."""
        result = parse_dict_input('{"product_id":9547}')
        assert result == {"product_id": 9547}

    @pytest.mark.unit
    def test_single_product_id_array_as_string(self) -> None:
        """Test single product_id as array in JSON string format."""
        result = parse_dict_input('{"product_id":[9547]}')
        assert result == {"product_id": [9547]}
