"""Tests for GitHub client."""

import pytest
from unittest.mock import Mock, patch
from github import GithubException

from wcg.github_client import GitHubClient


class TestGitHubClient:
    """Test GitHub client."""
    
    def test_empty_token_raises_error(self):
        """Test that empty token raises ValueError with helpful message."""
        with pytest.raises(ValueError) as exc_info:
            GitHubClient("")
        
        assert "GitHub token is missing or invalid" in str(exc_info.value)
        assert "https://github.com/settings/tokens" in str(exc_info.value)
    
    def test_placeholder_token_raises_error(self):
        """Test that placeholder token raises ValueError."""
        with pytest.raises(ValueError) as exc_info:
            GitHubClient("your-github-token-here")
        
        assert "GitHub token is missing or invalid" in str(exc_info.value)
    
    def test_whitespace_token_raises_error(self):
        """Test that whitespace-only token raises ValueError."""
        with pytest.raises(ValueError) as exc_info:
            GitHubClient("   ")
        
        assert "GitHub token is missing or invalid" in str(exc_info.value)
    
    @patch('wcg.github_client.Github')
    def test_invalid_token_raises_error(self, mock_github_class):
        """Test that invalid token raises ValueError with helpful message."""
        mock_github = Mock()
        mock_github.get_user.side_effect = Exception("401 Bad credentials")
        mock_github_class.return_value = mock_github
        
        with pytest.raises(ValueError) as exc_info:
            GitHubClient("invalid-token")
        
        error_msg = str(exc_info.value)
        assert "GitHub authentication failed" in error_msg
        assert "Invalid token or token has expired" in error_msg
        assert "repo" in error_msg
    
    @patch('wcg.github_client.Github')
    def test_valid_token_succeeds(self, mock_github_class):
        """Test that valid token initializes successfully."""
        mock_github = Mock()
        mock_user = Mock()
        mock_user.login = "test-user"
        mock_github.get_user.return_value = mock_user
        mock_github_class.return_value = mock_github
        
        client = GitHubClient("valid-token")
        assert client.github is not None
    
    @patch('wcg.github_client.Github')
    def test_get_commits_401_error(self, mock_github_class):
        """Test that 401 error in get_commits provides helpful message."""
        mock_github = Mock()
        mock_user = Mock()
        mock_user.login = "test-user"
        mock_github.get_user.return_value = mock_user
        
        mock_repo = Mock()
        mock_github.get_repo.return_value = mock_repo
        
        # Simulate 401 error
        github_exception = GithubException(401, {"message": "Bad credentials"}, None)
        mock_repo.get_commits.side_effect = github_exception
        
        mock_github_class.return_value = mock_github
        
        client = GitHubClient("valid-token")
        
        with pytest.raises(ValueError) as exc_info:
            client.get_commits_last_24h("test/repo", "main")
        
        error_msg = str(exc_info.value)
        assert "authentication failed" in error_msg.lower()
        assert "test/repo" in error_msg
        assert "main" in error_msg
    
    @patch('wcg.github_client.Github')
    def test_get_commits_403_error(self, mock_github_class):
        """Test that 403 error in get_commits provides helpful message."""
        mock_github = Mock()
        mock_user = Mock()
        mock_user.login = "test-user"
        mock_github.get_user.return_value = mock_user
        
        mock_repo = Mock()
        mock_github.get_repo.return_value = mock_repo
        
        # Simulate 403 error
        github_exception = GithubException(403, {"message": "Forbidden"}, None)
        mock_repo.get_commits.side_effect = github_exception
        
        mock_github_class.return_value = mock_github
        
        client = GitHubClient("valid-token")
        
        with pytest.raises(ValueError) as exc_info:
            client.get_commits_last_24h("test/repo", "main")
        
        error_msg = str(exc_info.value)
        assert "access denied" in error_msg.lower()
        assert "repo" in error_msg.lower()
    
    @patch('wcg.github_client.Github')
    def test_get_commits_404_error(self, mock_github_class):
        """Test that 404 error in get_commits provides helpful message."""
        mock_github = Mock()
        mock_user = Mock()
        mock_user.login = "test-user"
        mock_github.get_user.return_value = mock_user
        
        mock_repo = Mock()
        mock_github.get_repo.return_value = mock_repo
        
        # Simulate 404 error
        github_exception = GithubException(404, {"message": "Not Found"}, None)
        mock_repo.get_commits.side_effect = github_exception
        
        mock_github_class.return_value = mock_github
        
        client = GitHubClient("valid-token")
        
        with pytest.raises(ValueError) as exc_info:
            client.get_commits_last_24h("test/repo", "main")
        
        error_msg = str(exc_info.value)
        assert "not found" in error_msg.lower()
        assert "test/repo" in error_msg
        assert "main" in error_msg
