#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
批量修复ArrayList未指定容量的违规
使用上下文分析推断合适容量
"""

import re
from pathlib import Path

def find_size_hint(content: str, var_name: str, max_lines: int = 20) -> str:
    """查找变量使用上下文来推断容量"""
    lines = content.split('\n')

    for i, line in enumerate(lines):
        if var_name in line:
            # 查找类似 xxx.size() 的调用
            if f'{var_name}.size()' in line:
                # 提取 size() 前的变量
                match = re.search(rf'(\w+)\.size\(\)', line)
                if match:
                    return f'{match.group(1)}.size()'
            # 查找 for (Xxx xxx : xxxList) 模式
            match = re.search(rf'for\s*\([^)]+\s+:\s+{re.escape(var_name)}\)', line)
            if match:
                return None  # 无法推断

    return None

def fix_file(file_path: Path) -> tuple:
    """修复单个文件，返回(修改数, 详情列表)"""
    try:
        content = file_path.read_text(encoding='utf-8')
        original = content

        lines = content.split('\n')
        new_lines = []
        changes = []

        for i, line in enumerate(lines):
            new_line = line

            # 匹配 new ArrayList<>() 但排除已有容量的
            if re.search(r'new\s+ArrayList<>\(\)', line):
                # 跳过已有容量的
                if 'new ArrayList<>(16)' in line or 'new ArrayList<>(预估' in line:
                    new_lines.append(new_line)
                    continue

                # 跳过注释行
                stripped = line.strip()
                if stripped.startswith('//') or stripped.startswith('*') or stripped.startswith('/*'):
                    new_lines.append(new_line)
                    continue

                # 尝试找到赋值语句来确定变量名和可能的容量来源
                # 模式1: List<Xxx> xxx = new ArrayList<>();
                match = re.search(r'List<[^>]+>\s+(\w+)\s*=\s*new\s+ArrayList<>\(\)', line)
                if match:
                    var_name = match.group(1)
                    # 在后续行中查找可能的容量来源
                    hint = None
                    for j in range(i+1, min(i+10, len(lines))):
                        next_line = lines[j]
                        # 查找 xxx.size() 作为容量
                        if f'{var_name}.size()' in next_line:
                            # 查找 size() 前的变量
                            size_match = re.search(r'(\w+)\.size\(\)', next_line)
                            if size_match and size_match.group(1) != var_name:
                                hint = f'{size_match.group(1)}.size()'
                                break
                        # 查找 for (X : xxx) 或 for (X : xxxList)
                        for_match = re.search(r'for\s*\([^)]+:\s*(\w+)\)', next_line)
                        if for_match and for_match.group(1) == var_name:
                            # 向前查找可能的集合源
                            for k in range(i-1, max(0, i-10), -1):
                                prev_line = lines[k]
                                # 查找参数 List<Xxx> xxx
                                param_match = re.search(r'List<[^>]+>\s+(\w+)', prev_line)
                                if param_match and param_match.group(1) == var_name:
                                    hint = None  # 来自参数，无法确定
                                    break
                                # 查找 xxx.size()
                                if f'.size()' in prev_line:
                                    size_match = re.search(r'(\w+)\.size\(\)', prev_line)
                                    if size_match:
                                        hint = f'{size_match.group(1)}.size()'
                                        break

                    if hint:
                        new_line = line.replace('new ArrayList<>()', f'new ArrayList<>({hint})')
                        changes.append(f"  {var_name} -> {hint}")
                    else:
                        # 默认16容量
                        new_line = line.replace('new ArrayList<>()', 'new ArrayList<>(16)')
                        changes.append(f"  {var_name} -> 16 (默认)")
                else:
                    # 其他模式，直接改为16容量
                    new_line = line.replace('new ArrayList<>()', 'new ArrayList<>(16)')

            new_lines.append(new_line)

        if changes:
            file_path.write_text('\n'.join(new_lines), encoding='utf-8')
            return len(changes), changes
        return 0, []
    except Exception as e:
        print(f"  错误 {file_path}: {e}")
        return 0, []

def main():
    base_path = Path('services')
    total_changes = 0
    files_fixed = 0

    print("修复 ArrayList 初始容量...")
    print("=" * 60)

    for java_file in base_path.rglob('*.java'):
        if 'target' in str(java_file) or '\\test\\' in str(java_file):
            continue

        try:
            content = java_file.read_text(encoding='utf-8')
            if 'new ArrayList<>()' not in content:
                continue

            changes, details = fix_file(java_file)
            if changes > 0:
                rel_path = java_file.relative_to(base_path)
                print(f"\n{rel_path}")
                for d in details:
                    print(d)
                total_changes += changes
                files_fixed += 1
        except Exception as e:
            print(f"  错误: {e}")

    print("\n" + "=" * 60)
    print(f"修复完成: {files_fixed} 个文件, {total_changes} 处变更")

if __name__ == '__main__':
    main()
