from unittest.mock import MagicMock, patch

import pytest

from GramAddict.core.behaviors.comment import CommentPlugin


@pytest.fixture
def comment_plugin():
    return CommentPlugin()


@pytest.fixture
def mock_context():
    ctx = MagicMock()
    ctx.configs = MagicMock()
    ctx.configs.get_plugin_config.return_value = {"percentage": 50}
    ctx.configs.args.dry_run_comments = False
    ctx.shared_state = {"res_score": 1.0}
    ctx.context_xml = "<xml></xml>"
    ctx.device = MagicMock()
    ctx.post_data = {"description": "test desc"}
    ctx.session_state = MagicMock()
    ctx.session_state.check_limit.return_value = False

    # Mock cognitive stack
    writer = MagicMock()
    writer.generate_comment.return_value = "Great post!"

    mock_nav = MagicMock()
    mock_nav.do.return_value = True

    ctx.cognitive_stack = {"writer": writer, "nav_graph": mock_nav}
    return ctx


class TestCommentPlugin:
    @patch("GramAddict.core.behaviors.comment.random.random", return_value=0.1)
    def test_can_activate_enabled(self, mock_random, comment_plugin, mock_context):
        assert comment_plugin.can_activate(mock_context) is True

    def test_can_activate_disabled_via_config(self, comment_plugin, mock_context):
        mock_context.configs.get_plugin_config.return_value = {"percentage": 0}
        assert comment_plugin.can_activate(mock_context) is False

    def test_execute_success(self, comment_plugin, mock_context):
        result = comment_plugin.execute(mock_context)

        assert result.executed is True
        assert result.interactions == 1

        mock_context.cognitive_stack["nav_graph"].do.assert_any_call("open comments")
        mock_context.cognitive_stack["nav_graph"].do.assert_any_call("type and post comment", text="Great post!")

    def test_execute_fails_type_and_post(self, comment_plugin, mock_context):
        def mock_do(intent, **kwargs):
            if intent == "type and post comment":
                return False
            return True

        mock_context.cognitive_stack["nav_graph"].do.side_effect = mock_do

        result = comment_plugin.execute(mock_context)

        assert result.executed is False
        mock_context.cognitive_stack["nav_graph"].do.assert_any_call("open comments")
