"""
PM-Agent v1.2.0 Database Coverage Tests

使用测试数据库覆盖数据库相关代码
"""
import os
import sys
import pytest
import tempfile
from pathlib import Path
from unittest.mock import Mock, patch
from datetime import datetime

sys.path.insert(0, str(Path(__file__).parent.parent))
sys.path.insert(0, str(Path(__file__).parent.parent.parent))


class TestDatabaseCoverage:
    """数据库覆盖率测试"""

    def test_sync_permission_with_db(self):
        """测试带数据库的同步权限"""
        from backend.services.sync_permission_service import SyncPermissionService
        
        service = SyncPermissionService()
        
        result = service.can_sync_project("test-project")
        
        assert result is not None

    def test_sync_permission_confidential_with_db(self):
        """测试保密项目权限"""
        from backend.services.sync_permission_service import SyncPermissionService
        
        service = SyncPermissionService()
        
        result = service.can_sync_project("confidential-project")
        
        assert result is not None

    def test_should_warn_with_db(self):
        """测试带数据库的警告"""
        from backend.services.sync_permission_service import SyncPermissionService
        
        service = SyncPermissionService()
        
        should_warn, reason = service.should_warn_before_manual_sync("test-project")
        
        assert isinstance(should_warn, bool)

    def test_should_warn_confidential_with_db(self):
        """测试保密项目警告"""
        from backend.services.sync_permission_service import SyncPermissionService
        
        service = SyncPermissionService()
        
        should_warn, reason = service.should_warn_before_manual_sync("confidential-project")
        
        assert isinstance(should_warn, bool)

    def test_get_confidential_projects_with_db(self):
        """测试获取保密项目"""
        from backend.services.sync_permission_service import SyncPermissionService
        
        service = SyncPermissionService()
        
        projects = service._get_confidential_active_projects()
        
        assert isinstance(projects, list)

    def test_check_sync_safety_with_db(self):
        """测试带数据库的安全检查"""
        from backend.services.sync_permission_service import SyncPermissionService
        
        service = SyncPermissionService()
        
        result = service.check_sync_safety("test-project")
        
        assert 'is_safe' in result

    def test_check_sync_safety_confidential_with_db(self):
        """测试保密项目安全检查"""
        from backend.services.sync_permission_service import SyncPermissionService
        
        service = SyncPermissionService()
        
        result = service.check_sync_safety("confidential-project")
        
        assert 'is_safe' in result


class TestProgressWithDB:
    """带数据库的进度测试"""

    def test_progress_with_db_client(self):
        """测试带数据库客户端"""
        from backend.services.progress_service import ProgressService
        
        service = ProgressService()
        
        progress = service.get_project_progress("test-project")
        
        assert progress is not None


class TestDocumentFetcherWithDB:
    """带数据库的文档测试"""

    def test_sync_to_database(self):
        """测试同步到数据库"""
        from backend.services.document_fetcher import DocumentFetcher
        import sqlite3
        
        temp = tempfile.mkdtemp()
        try:
            # Create test project in database
            db_path = 'backend/data/pm_agent_test.db'
            conn = sqlite3.connect(db_path)
            cursor = conn.cursor()
            cursor.execute("INSERT OR IGNORE INTO projects (name, status) VALUES (?, 'active')", 
                         (os.path.basename(temp),))
            conn.commit()
            conn.close()
            
            fetcher = DocumentFetcher(base_path=temp)
            
            # Create test file
            with open(os.path.join(temp, "test.md"), "w") as f:
                f.write("# Test")
            
            # Test sync
            from backend.models.database import get_db
            db = next(get_db())
            fetcher.sync_to_database(os.path.basename(temp), db_session=db)
            
        finally:
            import shutil
            shutil.rmtree(temp, ignore_errors=True)


class TestGitSyncWithDB:
    """带数据库的Git测试"""

    def test_sync_to_database(self):
        """测试Git同步到数据库"""
        from backend.services.git_sync_service import GitSyncService
        from backend.models.database import get_db
        
        temp = tempfile.mkdtemp()
        try:
            # Create test project
            db = next(get_db())
            
            from backend.models.database import Project
            project = db.query(Project).filter(Project.name == "test-project").first()
            
            if project:
                # Test saving sync result
                service = GitSyncService()
                result = service.sync_project("test-project")
                
                assert result is not None
        finally:
            import shutil
            shutil.rmtree(temp, ignore_errors=True)


class TestIssueSyncWithDB:
    """带数据库的问题同步测试"""

    def test_save_to_db(self):
        """测试保存到数据库"""
        from backend.services.issue_sync_service import IssueSyncService, SyncBug
        from backend.models.database import get_db
        
        db = next(get_db())
        
        service = IssueSyncService()
        
        bugs = [
            SyncBug(
                id="TEST-001",
                title="Test bug",
                status="open",
                severity="high"
            )
        ]
        
        service.save_bugs_to_db("test-project", bugs, db)


class TestStatusFeedbackWithDB:
    """带数据库的状态反馈测试"""

    def test_save_change_to_db(self):
        """测试保存变更到数据库"""
        from backend.services.status_feedback_service import StatusFeedbackService, ChangeEvent, ChangeType
        from backend.models.database import get_db
        
        db = next(get_db())
        
        mock_storage = Mock()
        mock_storage.save_change.return_value = True
        
        service = StatusFeedbackService(storage=mock_storage)
        
        event = ChangeEvent(
            project_name="test-project",
            change_type=ChangeType.BUG,
            change_id="BUG-001",
            title="Test",
            old_status="open",
            new_status="closed"
        )
        
        service.update_local_status([event])


if __name__ == "__main__":
    pytest.main([__file__, "-v", "--tb=short"])
