#!/usr/bin/env python3
# ================= MOMO 系統 - Aider Code Review 自動化腳本 =================
# 功能：程式完成後自動觸發 Aider 進行 Code Review
# 作者：AI Assistant
# 版本：1.0
# =======================================================================

import argparse
import os
import subprocess
import sys
from datetime import datetime
from pathlib import Path

# 導入工具類
try:
    from scripts.code_review_utils import CodeReviewLogger, CodeReviewConfig, CodeReviewValidator, GitHelper
except ImportError:
    # 嘗試直接導入（當在scripts目錄中執行時）
    try:
        from code_review_utils import CodeReviewLogger, CodeReviewConfig, CodeReviewValidator, GitHelper
    except ImportError:
        print("❌ 無法導入工具類，請確保 code_review_utils.py 存在")
        sys.exit(1)


class AiderCodeReview:
    def __init__(self, project_root=None):
        self.project_root = Path(project_root) if project_root else Path(__file__).parent.parent
        
        # 初始化工具類
        self.logger = CodeReviewLogger(self.project_root)
        self.config = CodeReviewConfig(self.project_root)
        self.validator = CodeReviewValidator()
        self.git_helper = GitHelper(self.project_root)
        
        # 檢查Git倉庫
        if not self.git_helper.is_git_repository():
            self.logger.warning("當前目錄不是Git倉庫，某些功能可能無法使用")
        
        # 檢查Aider路徑
        self.aider_path = self.config.get("aider.path", "/Users/ooo/.local/bin/aider")
        if not Path(self.aider_path).exists():
            self.logger.error(f"Aider 路徑不存在: {self.aider_path}")
            
    def log_review(self, message):
        """記錄Code Review日誌（保持向後兼容）"""
        self.logger.info(message)

    def get_changed_files(self, git_diff_filter="ACM"):
        """獲取Git中變更的檔案"""
        try:
            # 使用GitHelper獲取變更檔案
            all_changed = self.git_helper.get_changed_files(
                diff_filter=git_diff_filter,
                use_staged=self.config.get("git.use_staged", True)
            )
            
            # 過滤允許的檔案類型
            allowed_extensions = self.config.get("file_filters.allowed_extensions", 
                                           ['.py', '.js', '.ts', '.jsx', '.tsx', '.html', '.css'])
            
            filtered_files = []
            for file_path in all_changed:
                if any(file_path.endswith(ext) for ext in allowed_extensions):
                    # 檢查檔案是否存在且大小合理
                    abs_path = self.project_root / file_path
                    if abs_path.exists() and abs_path.is_file():
                        file_size = abs_path.stat().st_size
                        max_size = self.config.get("file_filters.max_file_size", 10485760)
                        if file_size <= max_size:
                            filtered_files.append(file_path)
                        else:
                            self.logger.warning(f"檔案過大，跳過: {file_path} ({file_size} bytes)")
                    else:
                        self.logger.warning(f"檔案不存在，跳過: {file_path}")
            
            return filtered_files
            
        except Exception as e:
            self.logger.error("獲取變更檔案失敗", e)
            return []

    def run_aider_review(self, files=None, review_type="basic"):
        """執行Aider Code Review"""
        if not files:
            files = self.get_changed_files()
        
        if not files:
            self.log_review("📝 沒有需要Review的檔案")
            return True
        
        # 驗證Review類型
        if not self.validator.validate_review_type(review_type):
            self.logger.error(f"無效的Review類型: {review_type}")
            return False
        
        # 驗證檔案
        valid_files = self.validator.validate_files(files, self.project_root)
        if not valid_files:
            self.logger.error("沒有有效的檔案可以Review")
            return False
        
        # 構建Aider命令
        cmd = [self.aider_path]
        
        # 從配置獲取Review類型對應的訊息
        review_message = self.config.get(f"review_types.{review_type}.message")
        if not review_message:
            self.logger.error(f"找不到Review類型 {review_type} 的配置")
            return False
        
        # 添加Aider參數
        if self.config.get("aider.auto_yes", False):
            cmd.append("--yes")
        
        if self.config.get("aider.no_git", True):
            cmd.append("--no-git")
        
        cmd.extend(["--message", review_message])
        
        # 添加要review的檔案
        cmd.extend(valid_files)
        
        self.log_review(f"🔍 開始Code Review - 類型: {review_type}, 檔案: {', '.join(valid_files)}")
        
        try:
            # 設置環境變數
            env = os.environ.copy()
            env["PYTHONPATH"] = str(self.project_root)
            
            # 執行Aider
            timeout = self.config.get("aider.timeout", 600)
            result = subprocess.run(
                cmd,
                cwd=self.project_root,
                capture_output=True,
                text=True,
                env=env,
                timeout=timeout
            )
            
            if result.returncode == 0:
                self.log_review("✅ Code Review 完成")
                # 保存Review結果
                self.save_review_result(valid_files, result.stdout, review_type)
                return True
            else:
                self.logger.error(f"Code Review 失敗: {result.stderr}")
                return False
                
        except subprocess.TimeoutExpired:
            self.logger.error("Code Review 超時")
            return False
        except Exception as e:
            self.logger.error("Code Review 異常", e)
            return False

    def save_review_result(self, files, output, review_type):
        """保存Review結果到檔案"""
        try:
            timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
            safe_review_type = self.validator.sanitize_filename(review_type)
            result_file = self.project_root / "logs" / f"review_{safe_review_type}_{timestamp}.md"

            content = f"""# Code Review 報告

**時間**: {datetime.now().strftime("%Y-%m-%d %H:%M:%S")}
**類型**: {review_type}
**檔案**: {', '.join(files)}
**Aider版本**: {self.aider_path}

## Review 結果

```
{output}
```

## 執行資訊

- **專案根目錄**: {self.project_root}
- **檔案數量**: {len(files)}
- **Review類型**: {review_type}
- **執行時間**: {datetime.now().strftime("%Y-%m-%d %H:%M:%S")}

---
*由 Aider 自動生成 - MOMO 系統 Code Review*
"""

            with open(result_file, "w", encoding="utf-8") as f:
                f.write(content)

            self.log_review(f"📄 Review結果已保存: {result_file}")
            
        except Exception as e:
            self.logger.error("保存Review結果失敗", e)

    def review_specific_files(self, file_paths, review_type="basic"):
        """Review指定的檔案"""
        try:
            # 驗證Review類型
            if not self.validator.validate_review_type(review_type):
                self.logger.error(f"無效的Review類型: {review_type}")
                return False
            
            # 驗證並處理檔案路徑
            valid_files = self.validator.validate_files(file_paths, self.project_root)
            if not valid_files:
                self.logger.error("沒有有效的檔案可以Review")
                return False

            return self.run_aider_review(valid_files, review_type)
            
        except Exception as e:
            self.logger.error("Review指定檔案失敗", e)
            return False


def main():
    try:
        parser = argparse.ArgumentParser(
            description="MOMO系統 Aider Code Review 自動化工具",
            formatter_class=argparse.RawDescriptionHelpFormatter,
            epilog="""
使用範例:
  %(prog)s --auto                           # 自動Review暫存檔案
  %(prog)s --files app.py routes/*.py         # Review指定檔案
  %(prog)s --type security --auto              # 安全檢查暫存檔案
  %(prog)s --project-root /path/to/project    # 指定專案根目錄
            """
        )
        parser.add_argument("--files", "-f", nargs="+", 
                          help="指定要Review的檔案（支援相對路徑和絕對路徑）")
        parser.add_argument("--type", "-t", choices=["basic", "security", "performance"],
                          default="basic", help="Review類型 (預設: basic)")
        parser.add_argument("--project-root", "-p", 
                          help="專案根目錄路徑（預設: 自動偵測）")
        parser.add_argument("--auto", "-a", action="store_true",
                          help="自動Review暫存的檔案 (Git staged files)")
        parser.add_argument("--verbose", "-v", action="store_true",
                          help="顯示詳細輸出")
        parser.add_argument("--dry-run", action="store_true",
                          help="僅顯示將要Review的檔案，不實際執行")

        args = parser.parse_args()

        # 初始化Code Review工具
        reviewer = AiderCodeReview(args.project_root)
        
        if args.verbose:
            reviewer.logger.info(f"🔧 使用專案根目錄: {reviewer.project_root}")
            reviewer.logger.info(f"🔧 Aider 路徑: {reviewer.aider_path}")

        success = False
        
        if args.dry_run:
            # 乾運行模式
            if args.auto:
                files = reviewer.get_changed_files()
                reviewer.logger.info(f"🔍 將Review的暫存檔案: {', '.join(files)}")
            elif args.files:
                valid_files = reviewer.validator.validate_files(args.files, reviewer.project_root)
                reviewer.logger.info(f"🔍 將Review的指定檔案: {', '.join(valid_files)}")
            else:
                files = reviewer.get_changed_files()
                reviewer.logger.info(f"🔍 將Review的變更檔案: {', '.join(files)}")
            success = True
        elif args.auto:
            # 自動Review暫存的檔案
            reviewer.logger.info("🚀 開始自動Review暫存檔案...")
            success = reviewer.run_aider_review(review_type=args.type)
        elif args.files:
            # Review指定檔案
            reviewer.logger.info(f"🚀 開始Review指定檔案: {', '.join(args.files)}")
            success = reviewer.review_specific_files(args.files, args.type)
        else:
            # Review所有變更檔案
            reviewer.logger.info("🚀 開始Review所有變更檔案...")
            success = reviewer.run_aider_review(review_type=args.type)

        if success:
            reviewer.logger.info("✅ Code Review 流程完成")
            sys.exit(0)
        else:
            reviewer.logger.error("❌ Code Review 流程失敗")
            sys.exit(1)
            
    except KeyboardInterrupt:
        print("\n⚠️ 用戶中斷操作")
        sys.exit(130)
    except Exception as e:
        print(f"❌ 程式執行錯誤: {e}")
        if "--verbose" in sys.argv or "-v" in sys.argv:
            import traceback
            traceback.print_exc()
        sys.exit(1)


if __name__ == "__main__":
    main()
