"""
同步权限控制服务 - F029

功能: 保密项目自动同步控制

 """

import logging
from typing import Tuple, List, Dict, Optional
from dataclasses import dataclass


logger = logging.getLogger(__name__)


@dataclass
class SyncPermission:
    """同步权限"""
    allowed: bool
    reason: str
    requires_confirmation: bool = False
    warnings: List[str] = None


class SyncPermissionService:
    """同步权限控制服务"""
    
    def __init__(self, db_session=None):
        """
        初始化
        
        Args:
            db_session: 数据库会话
        """
        self.db = db_session
        self.logger = logging.getLogger(__name__)
    
    def can_auto_sync(self) -> SyncPermission:
        """
        检查是否允许自动同步
        
        Returns:
            SyncPermission: 同步权限结果
        """
        confidential_projects = self._get_confidential_active_projects()
        
        if confidential_projects:
            return SyncPermission(
                allowed=False,
                reason=f"存在 {len(confidential_projects)} 个活跃保密项目，禁用自动同步",
                requires_confirmation=True,
                warnings=[f"项目 '{p['name']}' 是保密项目" for p in confidential_projects]
            )
        
        return SyncPermission(
            allowed=True,
            reason="允许自动同步"
        )
    
    def can_sync_project(self, project_name: str) -> SyncPermission:
        """
        检查是否可以同步指定项目
        
        Args:
            project_name: 项目名称
            
        Returns:
            SyncPermission: 同步权限结果
        """
        project = self._get_project(project_name)
        
        if not project:
            return SyncPermission(
                allowed=False,
                reason=f"项目 '{project_name}' 不存在"
            )
        
        if project.get('confidentiality') == 'confidential':
            warnings = self._get_project_warnings(project_name)
            return SyncPermission(
                allowed=True,
                reason="保密项目可以手动同步",
                requires_confirmation=True,
                warnings=warnings
            )
        
        return SyncPermission(
            allowed=True,
            reason=f"项目 '{project_name}' 是普通项目，允许同步"
        )
    
    def should_warn_before_manual_sync(self, project_name: str = None) -> Tuple[bool, str]:
        """
        检查手动同步是否需要警告
        
        Args:
            project_name: 项目名称（可选）
            
        Returns:
            (是否需要警告, 原因)
        """
        if project_name:
            project = self._get_project(project_name)
            if project and project.get('confidentiality') == 'confidential':
                return True, f"项目 '{project_name}' 是保密项目，同步前请确认"
            
            return False, ""
        
        confidential_count = len(self._get_confidential_active_projects())
        
        if confidential_count > 0:
            return True, f"系统中存在 {confidential_count} 个保密项目"
        
        return False, ""
    
    def get_sync_recommendation(self, project_name: str = None) -> Dict:
        """
        获取同步建议
        
        Args:
            project_name: 项目名称（可选）
            
        Returns:
            Dict: 同步建议
        """
        if project_name:
            permission = self.can_sync_project(project_name)
            return {
                'project_name': project_name,
                'can_sync': permission.allowed,
                'reason': permission.reason,
                'requires_confirmation': permission.requires_confirmation,
                'warnings': permission.warnings or []
            }
        
        auto_sync = self.can_auto_sync()
        confidential_projects = self._get_confidential_active_projects()
        
        return {
            'auto_sync_allowed': auto_sync.allowed,
            'auto_sync_reason': auto_sync.reason,
            'confidential_projects_count': len(confidential_projects),
            'confidential_projects': [p['name'] for p in confidential_projects],
            'recommendations': self._generate_recommendations()
        }
    
    def _generate_recommendations(self) -> List[str]:
        """生成同步建议"""
        recommendations = []
        
        confidential_count = len(self._get_confidential_active_projects())
        
        if confidential_count > 0:
            recommendations.append("建议仅同步必要的文档到保密项目")
            recommendations.append("同步前请检查是否包含敏感信息")
            recommendations.append("建议使用手动同步代替自动同步")
        
        recommendations.append("定期检查同步日志，确保没有敏感信息泄漏")
        recommendations.append("及时更新保密项目的同步规则")
        
        return recommendations
    
    def _get_confidential_active_projects(self) -> List[Dict]:
        """获取活跃的保密项目"""
        try:
            from backend.models.database import Project, get_db
            
            db = next(get_db())
            try:
                projects = db.query(Project).filter(
                    Project.confidentiality == 'confidential',
                    Project.status == 'active'
                ).all()
                
                return [{'id': p.id, 'name': p.name} for p in projects]
            finally:
                db.close()
        except Exception as e:
            self.logger.error(f"获取保密项目失败: {e}")
            return []
    
    def _get_project(self, project_name: str) -> Optional[Dict]:
        """获取项目信息"""
        try:
            from backend.models.database import Project, get_db
            
            db = next(get_db())
            try:
                project = db.query(Project).filter(Project.name == project_name).first()
                if project:
                    return {
                        'id': project.id,
                        'name': project.name,
                        'confidentiality': project.confidentiality,
                        'status': project.status,
                        'git_repo': project.git_repo
                    }
                return None
            finally:
                db.close()
        except Exception as e:
            self.logger.error(f"获取项目失败: {e}")
            return None
    
    def _get_project_warnings(self, project_name: str) -> List[str]:
        """获取项目警告信息"""
        warnings = []
        
        project = self._get_project(project_name)
        if not project:
            return [f"项目 '{project_name}' 不存在"]
        
        if project.get('confidentiality') == 'confidential':
            warnings.append(f"项目 '{project_name}' 是保密项目")
            warnings.append("同步可能包含敏感信息，请谨慎操作")
            
            if project.get('git_repo'):
                warnings.append(f"Git仓库: {project['git_repo']}")
        
        return warnings
    
    def check_sync_safety(self, project_name: str) -> Dict:
        """
        检查同步安全性
        
        Args:
            project_name: 项目名称
            
        Returns:
            Dict: 安全性检查结果
        """
        result = {
            'project_name': project_name,
            'is_safe': True,
            'checks': [],
            'warnings': []
        }
        
        project = self._get_project(project_name)
        if not project:
            result['is_safe'] = False
            result['checks'].append({
                'name': '项目存在',
                'passed': False,
                'message': f"项目 '{project_name}' 不存在"
            })
            return result
        
        result['checks'].append({
            'name': '项目存在',
            'passed': True,
            'message': f"项目 '{project_name}' 存在"
        })
        
        if project.get('confidentiality') == 'confidential':
            result['is_safe'] = False
            result['warnings'].append("这是保密项目，需要额外注意")
            result['checks'].append({
                'name': '保密级别',
                'passed': True,
                'message': f"保密级别: {project['confidentiality']}"
            })
        else:
            result['checks'].append({
                'name': '保密级别',
                'passed': True,
                'message': f"保密级别: {project.get('confidentiality', 'normal')}"
            })
        
        if project.get('status') != 'active':
            result['warnings'].append(f"项目状态: {project['status']}")
            result['checks'].append({
                'name': '项目状态',
                'passed': project.get('status') == 'active',
                'message': f"项目状态: {project.get('status')}"
            })
        
        return result
    
    def get_confidential_projects_summary(self) -> Dict:
        """获取保密项目汇总"""
        confidential_projects = self._get_confidential_active_projects()
        
        return {
            'total_confidential_projects': len(confidential_projects),
            'projects': confidential_projects,
            'auto_sync_recommended': len(confidential_projects) == 0,
            'message': f"当前有 {len(confidential_projects)} 个活跃保密项目" if confidential_projects else "没有活跃保密项目"
        }
