"""Tests for infra_diagram.renderers.mermaid."""

from __future__ import annotations

from infra_diagram.models import InfraDiagram, InfraEdge, InfraGroup, InfraNode, NodeType, SourceType
from infra_diagram.renderers.mermaid import render_mermaid


def _make_diagram() -> InfraDiagram:
    d = InfraDiagram(title="Test", source_type=SourceType.TERRAFORM)
    d.add_node(InfraNode(id="vpc", name="main-vpc", node_type=NodeType.NETWORK, provider="aws"))
    d.add_node(InfraNode(id="ec2", name="web-server", node_type=NodeType.VM, provider="aws"))
    d.add_edge(InfraEdge(source="vpc", target="ec2", label="contains"))
    d.add_group(InfraGroup(id="aws", name="AWS", node_ids=["vpc", "ec2"]))
    return d


class TestRenderMermaid:
    def test_basic_output(self):
        d = _make_diagram()
        result = render_mermaid(d)
        assert "graph TB" in result

    def test_direction_lr(self):
        d = _make_diagram()
        result = render_mermaid(d, direction="LR")
        assert "graph LR" in result

    def test_direction_bt(self):
        d = _make_diagram()
        result = render_mermaid(d, direction="BT")
        assert "graph BT" in result

    def test_nodes_in_output(self):
        d = _make_diagram()
        result = render_mermaid(d)
        assert "main-vpc" in result
        assert "web-server" in result

    def test_edges_in_output(self):
        d = _make_diagram()
        result = render_mermaid(d)
        assert "contains" in result
        assert "-->" in result

    def test_subgraph_rendered(self):
        d = _make_diagram()
        result = render_mermaid(d)
        assert "subgraph aws" in result
        assert "end" in result

    def test_edge_without_label(self):
        d = InfraDiagram()
        d.add_node(InfraNode(id="a", name="A", node_type=NodeType.VM))
        d.add_node(InfraNode(id="b", name="B", node_type=NodeType.VM))
        d.add_edge(InfraEdge(source="a", target="b"))
        result = render_mermaid(d)
        assert "a --> b" in result

    def test_styles_applied(self):
        d = _make_diagram()
        result = render_mermaid(d)
        assert "style" in result
        assert "fill:" in result

    def test_empty_diagram(self):
        d = InfraDiagram()
        result = render_mermaid(d)
        assert "graph TB" in result

    def test_ungrouped_nodes(self):
        d = InfraDiagram()
        d.add_node(InfraNode(id="x", name="standalone", node_type=NodeType.VM))
        result = render_mermaid(d)
        assert "standalone" in result
        assert "subgraph" not in result

    def test_safe_id_used(self):
        d = InfraDiagram()
        d.add_node(InfraNode(id="a-b.c", name="node", node_type=NodeType.VM))
        result = render_mermaid(d)
        assert "a_b_c" in result

    def test_edge_skipped_for_missing_node(self):
        d = InfraDiagram()
        d.add_node(InfraNode(id="a", name="A", node_type=NodeType.VM))
        d.add_edge(InfraEdge(source="a", target="nonexistent"))
        result = render_mermaid(d)
        # Edge should be skipped (no crash)
        assert "nonexistent" not in result

    def test_multiple_edges(self):
        d = InfraDiagram()
        d.add_node(InfraNode(id="a", name="A", node_type=NodeType.VM))
        d.add_node(InfraNode(id="b", name="B", node_type=NodeType.DATABASE))
        d.add_node(InfraNode(id="c", name="C", node_type=NodeType.CACHE))
        d.add_edge(InfraEdge(source="a", target="b", label="reads"))
        d.add_edge(InfraEdge(source="a", target="c", label="caches"))
        result = render_mermaid(d)
        assert "reads" in result
        assert "caches" in result
