from unittest.mock import MagicMock, patch

import pytest

from GramAddict.core.behaviors import BehaviorContext
from GramAddict.core.behaviors.perfect_snapping import PerfectSnappingPlugin


@pytest.fixture
def perfect_snapping():
    return PerfectSnappingPlugin()


@pytest.fixture
def mock_context():
    ctx = BehaviorContext(
        device=MagicMock(),
        configs=MagicMock(),
        session_state=MagicMock(),
        cognitive_stack={},
        context_xml="<xml>old</xml>",
    )
    return ctx


class TestPerfectSnappingPlugin:
    @patch("GramAddict.core.behaviors.perfect_snapping._align_active_post")
    def test_execute_no_alignment_needed(self, mock_align, perfect_snapping, mock_context):
        mock_align.return_value = False

        result = perfect_snapping.execute(mock_context)

        assert result.executed is False
        assert mock_context.context_xml == "<xml>old</xml>"
        mock_align.assert_called_once_with(mock_context.device)

    @patch("GramAddict.core.behaviors.perfect_snapping._align_active_post")
    def test_execute_alignment_done(self, mock_align, perfect_snapping, mock_context):
        mock_align.return_value = True
        mock_context.device.dump_hierarchy.return_value = "<xml>new</xml>"

        result = perfect_snapping.execute(mock_context)

        assert result.executed is True
        assert mock_context.context_xml == "<xml>new</xml>"
        mock_align.assert_called_once_with(mock_context.device)

    @patch("GramAddict.core.behaviors.perfect_snapping._align_active_post")
    def test_execute_alignment_with_radome(self, mock_align, perfect_snapping, mock_context):
        mock_align.return_value = True
        mock_context.device.dump_hierarchy.return_value = "<xml>new</xml>"

        mock_radome = MagicMock()
        mock_radome.sanitize_xml.return_value = "<xml>sanitized</xml>"
        mock_context.cognitive_stack["radome"] = mock_radome

        result = perfect_snapping.execute(mock_context)

        assert result.executed is True
        assert mock_context.context_xml == "<xml>sanitized</xml>"
        mock_radome.sanitize_xml.assert_called_once_with("<xml>new</xml>")
