from pathlib import Path
from unittest.mock import MagicMock, patch

from aider_gitea import solve_issue_in_repository


class TestSolveIssueInRepository:
    def setup_method(self):
        self.args = MagicMock()
        self.args.gitea_url = 'https://gitea.example.com'
        self.args.owner = 'test-owner'
        self.args.repo = 'test-repo'
        self.args.base_branch = 'main'

        self.gitea_client = MagicMock()
        self.tmpdirname = Path('/tmp/test-repo')
        self.branch_name = 'issue-123-test-branch'
        self.issue_title = 'Test Issue'
        self.issue_description = 'This is a test issue'
        self.issue_number = '123'

    @patch('aider_gitea.secrets.llm_api_keys', return_value='fake-api-key')
    @patch('aider_gitea.run_cmd')
    @patch('aider_gitea.push_changes')
    @patch('subprocess.run')
    def test_solve_issue_with_aider_changes(
        self,
        mock_subprocess_run,
        mock_push_changes,
        mock_run_cmd,
        mock_llm_api_key,
    ):
        # Setup mocks
        mock_run_cmd.return_value = True
        mock_push_changes.return_value = (
            True,
            '456',
            'https://gitea.example.com/test-owner/test-repo/pulls/456',
        )

        # Mock subprocess.run to return different commit hashes and file changes
        mock_subprocess_run.side_effect = [
            MagicMock(stdout='abc123\n', returncode=0),  # First git rev-parse
            MagicMock(
                stdout='file1.py\nfile2.py\n',
                returncode=0,
            ),  # git diff with changes
        ]

        # Call the function
        result = solve_issue_in_repository(
            self.args,
            self.tmpdirname,
            self.branch_name,
            self.issue_title,
            self.issue_description,
            self.issue_number,
            self.gitea_client,
        )

        # Verify results
        assert result is True
        assert mock_run_cmd.call_count >= 8  # Verify all expected commands were run
        mock_push_changes.assert_called_once()

    @patch('aider_gitea.secrets.llm_api_keys', return_value='fake-api-key')
    @patch('aider_gitea.run_cmd')
    @patch('aider_gitea.push_changes')
    @patch('subprocess.run')
    def test_solve_issue_without_aider_changes(
        self,
        mock_subprocess_run,
        mock_push_changes,
        mock_run_cmd,
        mock_llm_api_key,
    ):
        # Setup mocks
        mock_run_cmd.return_value = True
        mock_push_changes.return_value = (False, None, None)

        # Mock subprocess.run to return same commit hash and no file changes
        mock_subprocess_run.side_effect = [
            MagicMock(stdout='abc123\n', returncode=0),  # First git rev-parse
            MagicMock(stdout='', returncode=0),  # git diff with no changes
        ]

        # Call the function
        result = solve_issue_in_repository(
            self.args,
            self.tmpdirname,
            self.branch_name,
            self.issue_title,
            self.issue_description,
            self.issue_number,
            self.gitea_client,
        )

        # Verify results
        assert result is False
        assert mock_push_changes.call_count == 0  # push_changes should not be called