#!/usr/bin/env python3
import os
import re
import shutil
import sys
import yaml

def extract_version_from_string(input_string) -> dict:
    """
    从字符串中提取版本号，支持镜像名和文件夹名
    
    Args:
        input_string (str): 可以是Docker镜像名或文件夹名
        
    Returns:
        dict: 包含提取结果的字典 {success: bool, version: str}
    """
    if ':' in input_string:
        parts = input_string.split(':')
        candidate = parts[-1]
    else:
        candidate = os.path.basename(input_string)
    
    # 保存原始候选字符串用于失败时返回
    original_candidate = candidate
    
    # 从复杂标签中提取包含数字和分隔符的版本号部分
    pattern = r'(\d+(?:[\.\-]*\d+)+)'
    matches = re.findall(pattern, candidate)
    if matches:
        # 选择最长的匹配项，并统一分隔符为点号
        best_match = max(matches, key=len)
        normalized_version = re.sub(r'[\.\-]', '.', best_match)
        return {"success": True, "version": normalized_version}
    
    return {"success": False, "version": original_candidate}

def replace_version_in_dirname(old_ver_dir : str, new_version : str) -> str:
    """
    将旧版本文件夹名中的版本号替换为新版本号
    
    Args:
        old_ver_dir (str): 旧版本文件夹名
        new_version (str): 新版本号
        
    Returns:
        str: 新版本文件夹名
    """
    version_info = extract_version_from_string(old_ver_dir)
    
    if version_info["success"]:
        old_version = version_info["version"]
        new_ver_dir = old_ver_dir.replace(old_version, new_version)
        return new_ver_dir
    else:
        return new_version

def check_directory_contents(check_dir):
    print(f"{check_dir} 目录内容:")
    for item in os.listdir(check_dir):
        print(f"  - {item}")

def safe_rename_directory(old_path: str, new_path: str) -> bool:
    """
    安全地重命名目录，包含错误处理
    
    Args:
        old_path (str): 原目录路径
        new_path (str): 新目录路径
        
    Returns:
        bool: 重命名是否成功
    """
    try:
        if not os.path.exists(old_path):
            print(f"错误: 原目录不存在: {old_path}")
            return False
            
        if os.path.exists(new_path):
            print(f"错误: 目标目录已存在: {new_path}")
            return False
            
        print(f"将 {old_path} 重命名为 {new_path}")
        shutil.move(old_path, new_path)
        
        # 验证重命名是否成功
        if os.path.exists(new_path) and not os.path.exists(old_path):
            check_directory_contents(new_path)
            print(f"✓ 重命名成功")
            return True
        else:
            print(f"✗ 重命名后验证失败")
            return False
            
    except PermissionError as e:
        print(f"✗ 权限错误: {e}")
        return False
    except OSError as e:
        print(f"✗ 系统错误: {e}")
        return False
    except Exception as e:
        print(f"✗ 未知错误: {e}")
        return False

def write_version_file(file_path: str, version: str) -> bool:
    """
    写入版本标记文件
    
    Args:
        file_path (str): 版本标记文件路径
        version (str): 版本号
        
    Returns:
        bool: 写入是否成功
    """
    try:
        os.makedirs(os.path.dirname(file_path), exist_ok=True)
        with open(file_path, 'w') as f:
            f.write(version)
        print(f"✓ 版本标记文件已更新: {file_path}")
        return True
    except Exception as e:
        print(f"✗ 写入版本标记文件失败: {e}")
        return False

def main():
    app_name = sys.argv[1]
    old_ver_dir = sys.argv[2]
    
    docker_compose_file = f"apps/{app_name}/{old_ver_dir}/docker-compose.yml"
    
    if not os.path.exists(docker_compose_file):
        print(f"错误: 文件 {docker_compose_file} 不存在")
        sys.exit(1)
    
    with open(docker_compose_file, 'r') as f:
        compose_data = yaml.safe_load(f)
    
    services = compose_data.get('services', {})

    first_service = list(services.keys())[0]
    print(f"第一个服务是: {first_service}")
    
    image = services[first_service].get('image', '')
    print(f"该服务的镜像: {image}")
    
    new_version : str = extract_version_from_string(image).get("version", "latest")
    old_version : str = extract_version_from_string(old_ver_dir).get("version", "latest")
    print(f"旧版本号: {old_version}")
    print(f"新版本号: {new_version}")
    new_ver_dir = replace_version_in_dirname(old_ver_dir, new_version)
    if old_version != new_version:
        old_path = f"apps/{app_name}/{old_ver_dir}"
        new_path = f"apps/{app_name}/{new_ver_dir}"
        
        if safe_rename_directory(old_path, new_path):
            # 更新版本标记文件
            version_file = f"apps/{app_name}/{old_ver_dir}.version"
            if not write_version_file(version_file, new_ver_dir):
                print("版本标记文件更新失败，但目录重命名成功")
        else:
            print("错误: 目录重命名失败")
            sys.exit(1)

if __name__ == "__main__":
    main()