"""
Unit tests for orchestration.parameter_graph.

Author: Vasiliy Zdanovskiy
email: vasilyvz@gmail.com
"""

from mcp_proxy_adapter.core.orchestration.parameter_graph import build_parameter_graph


class TestBuildParameterGraph:
    """Tests for build_parameter_graph."""

    def test_none_schema_returns_empty(self):
        """None schema returns empty graph and empty required set."""
        graph, required = build_parameter_graph(None)
        assert graph == {}
        assert required == set()

    def test_non_dict_schema_returns_empty(self):
        """Non-dict schema returns empty graph and empty required set."""
        graph, required = build_parameter_graph(1)
        assert graph == {}
        assert required == set()
        graph, required = build_parameter_graph("x")
        assert graph == {}
        assert required == set()

    def test_empty_properties_returns_empty(self):
        """Schema without properties returns empty."""
        graph, required = build_parameter_graph({"type": "object"})
        assert graph == {}
        assert required == set()

    def test_properties_only_no_required(self):
        """Schema with properties but no required array."""
        schema = {"properties": {"a": {"type": "string"}, "b": {"type": "number"}}}
        graph, required = build_parameter_graph(schema)
        assert graph == {"a": set(), "b": set()}
        assert required == set()

    def test_properties_and_required(self):
        """Required set is intersection of required array and property names."""
        schema = {
            "properties": {"a": {}, "b": {}, "c": {}},
            "required": ["a", "c"],
        }
        graph, required = build_parameter_graph(schema)
        assert graph == {"a": set(), "b": set(), "c": set()}
        assert required == {"a", "c"}

    def test_required_ignores_unknown_names(self):
        """Required names not in properties are ignored."""
        schema = {
            "properties": {"a": {}},
            "required": ["a", "x", "y"],
        }
        _, required = build_parameter_graph(schema)
        assert required == {"a"}

    def test_depends_on_builds_edges(self):
        """dependsOn in property subschema adds graph edges."""
        schema = {
            "properties": {
                "a": {},
                "b": {"dependsOn": ["a"]},
                "c": {"dependsOn": ["b"]},
            },
            "required": ["c"],
        }
        graph, required = build_parameter_graph(schema)
        assert graph["a"] == set()
        assert graph["b"] == {"a"}
        assert graph["c"] == {"b"}
        assert required == {"a", "b", "c"}

    def test_dependencies_key_builds_edges(self):
        """dependencies key in property subschema adds graph edges."""
        schema = {
            "properties": {
                "x": {},
                "y": {"dependencies": ["x"]},
            },
            "required": ["y"],
        }
        graph, required = build_parameter_graph(schema)
        assert graph["y"] == {"x"}
        assert required == {"x", "y"}

    def test_depends_on_ignores_non_property_names(self):
        """dependsOn references to names not in properties are ignored."""
        schema = {
            "properties": {"a": {}, "b": {"dependsOn": ["a", "z"]}},
            "required": ["b"],
        }
        graph, required = build_parameter_graph(schema)
        assert graph["b"] == {"a"}
        assert required == {"a", "b"}

    def test_real_command_schema_echo(self):
        """Echo-like schema: no required, properties only."""
        schema = {
            "type": "object",
            "properties": {"message": {"type": "string", "default": "Hello"}},
            "additionalProperties": True,
        }
        graph, required = build_parameter_graph(schema)
        assert set(graph.keys()) == {"message"}
        assert required == set()

    def test_real_command_schema_job_status(self):
        """job_status-like schema: required array."""
        schema = {
            "type": "object",
            "properties": {"job_id": {"type": "string"}},
            "required": ["job_id"],
            "additionalProperties": True,
        }
        graph, required = build_parameter_graph(schema)
        assert set(graph.keys()) == {"job_id"}
        assert required == {"job_id"}
