"""
删除指定 Target 的宏定义内容
"""
import os, re
from ObjectiveC import oc_yaml
from ObjectiveC import oc_util

def delete_macro_content(target_name=None):
    """
    初始化函数，接收目标 Target 名称
    """
    if not target_name:
        print('错误: 未指定 Target 名称!')
        return
    
    path = oc_util.path_mix_project
    process_target_macros(path, target_name)

def isTrue(d):
    return (d.endswith('.xcodeproj')==False) and (d.endswith('.framework')==False) and (d not in oc_yaml.list_folder_ignore_all)

def process_target_macros(path, target_name):
    """
    处理项目中的 Target 宏定义
    """
    # print(f"开始处理 Target: {target_name}")
    
    # 确定要保留和删除的宏定义
    if target_name == "XXGPlayKitOS":
        keep_macro = "XXGPLAYKITOS_TARGET"
        remove_macro = "XXGPLAYKITCN_TARGET"
    elif target_name == "XXGPlayKitCN":
        keep_macro = "XXGPLAYKITCN_TARGET"
        remove_macro = "XXGPLAYKITOS_TARGET"
    else:
        print(f"错误: 不支持的 Target 名称: {target_name}")
        return
    
    # 遍历项目文件
    for root, dirs, files in os.walk(path, topdown=True):
        dirs[:] = [d for d in dirs if isTrue(d)]
        files[:] = [f for f in files if (os.path.splitext(f)[1] in oc_yaml.list_support_open_file_type) or (f=='contents')]
        
        for name in files:
            file_path = os.path.join(root, name)
            try:
                with open(file_path, 'r', encoding='utf-8') as f:
                    file_content = f.read()
                
                # 检查文件是否包含目标宏定义
                if f"#ifdef {keep_macro}" in file_content or f"#ifdef {remove_macro}" in file_content:
                    # 处理文件内容
                    modified_content = process_file_content(file_content, keep_macro, remove_macro)
                    
                    # 如果内容有变化，写回文件
                    if modified_content != file_content:
                        with open(file_path, 'w', encoding='utf-8') as f:
                            f.write(modified_content)
                        # print(f"已处理文件: {file_path}")
            except Exception as e:
                print(f"处理文件 {file_path} 时出错: {e}")

def process_file_content(content, keep_macro, remove_macro):
    """
    处理文件内容，删除不需要的宏定义块，保留需要的宏定义块的内容
    """
    # 1. 删除不需要保留的宏定义块 (#ifdef REMOVE_MACRO 到对应的 #endif)
    remove_pattern = rf'#ifdef\s+{remove_macro}.*?#endif'
    content = re.sub(remove_pattern, '', content, flags=re.DOTALL)
    
    # 2. 保留需要的宏定义块的内容，但删除 #ifdef KEEP_MACRO 和 #endif
    def replace_keep_macro(match):
        # 提取 #ifdef KEEP_MACRO 和 #endif 之间的内容
        full_match = match.group(0)
        # 查找第一行结束位置
        first_line_end = full_match.find('\n')
        if first_line_end == -1:
            return ''  # 如果没有换行符，返回空字符串
        
        # 查找最后一个 #endif 的位置
        last_endif = full_match.rfind('#endif')
        if last_endif == -1:
            return full_match  # 如果没有找到 #endif，返回原始内容
        
        # 提取中间内容（去掉首行 #ifdef 和尾行 #endif）
        middle_content = full_match[first_line_end+1:last_endif].strip()
        return middle_content
    
    keep_pattern = rf'#ifdef\s+{keep_macro}.*?#endif'
    content = re.sub(keep_pattern, replace_keep_macro, content, flags=re.DOTALL)
    
    # 3. 清理多余的空行
    content = re.sub(r'\n\s*\n\s*\n', '\n\n', content)
    
    return content

def delete_debug_macros(target_name=None):
    """
    删除所有 #ifdef XXGPLAYKIT_DEBUG 和 #endif 之间的内容
    不管是哪个 Target
    """
    # print("开始删除所有 XXGPLAYKIT_DEBUG 宏定义块")
    
    path = oc_util.path_mix_project
    debug_macro = "XXGPLAYKIT_DEBUG"
    
    # 遍历项目文件
    for root, dirs, files in os.walk(path, topdown=True):
        dirs[:] = [d for d in dirs if isTrue(d)]
        files[:] = [f for f in files if (os.path.splitext(f)[1] in oc_yaml.list_support_open_file_type) or (f=='contents')]
        
        for name in files:
            file_path = os.path.join(root, name)
            try:
                with open(file_path, 'r', encoding='utf-8') as f:
                    file_content = f.read()
                
                # 检查文件是否包含目标宏定义
                if f"#ifdef {debug_macro}" in file_content:
                    # 删除 #ifdef XXGPLAYKIT_DEBUG 到 #endif 之间的所有内容
                    modified_content = remove_debug_macro_content(file_content, debug_macro)
                    
                    # 如果内容有变化，写回文件
                    if modified_content != file_content:
                        with open(file_path, 'w', encoding='utf-8') as f:
                            f.write(modified_content)
                        # print(f"已删除 DEBUG 宏定义: {file_path}")
            except Exception as e:
                print(f"处理文件 {file_path} 时出错: {e}")
    
    print("XXGPLAYKIT_DEBUG 宏定义块删除完成")

def remove_debug_macro_content(content, debug_macro):
    """
    删除 #ifdef XXGPLAYKIT_DEBUG 到 #endif 之间的所有内容
    """
    # 匹配 #ifdef XXGPLAYKIT_DEBUG 到 #endif 之间的所有内容
    debug_pattern = rf'#ifdef\s+{debug_macro}.*?#endif'
    # 删除匹配的内容
    content = re.sub(debug_pattern, '', content, flags=re.DOTALL)
    
    # 清理多余的空行
    content = re.sub(r'\n\s*\n\s*\n', '\n\n', content)
    
    return content

# 示例：将 XXGPlayKit.bundle 重命名为 ProjectName.bundle
# from ObjectiveC.oc_custom import custom_file

# 方法1：使用默认项目路径
# custom_file.rename_specific_file('XXGPlayKit.bundle', 'ProjectName.bundle')

# 方法2：指定项目路径
# custom_file.rename_specific_file('XXGPlayKit.bundle', 'ProjectName.bundle', '/path/to/your/project')
def rename_specific_file(old_name, new_name, project_path=None):
    """
    修改工程中指定文件的名字
    
    参数:
        old_name (str): 要修改的文件名，例如 'XXGPlayKit.bundle'
        new_name (str): 新的文件名，例如 'ProjectName.bundle'
        project_path (str, optional): 项目路径，默认使用 oc_util.path_mix_project
    
    返回:
        bool: 操作成功返回 True，否则返回 False
    """
    if not project_path:
        project_path = oc_util.path_mix_project
    
    print(f"开始查找并重命名文件: {old_name} -> {new_name}")
    
    # 记录是否找到并修改了文件
    found_and_renamed = False
    
    # 遍历项目文件
    for root, dirs, files in os.walk(project_path, topdown=True):
        # 检查目录中是否有匹配的文件夹
        for dir_name in dirs:
            if dir_name == old_name:
                old_path = os.path.join(root, dir_name)
                new_path = os.path.join(root, new_name)
                
                try:
                    os.rename(old_path, new_path)
                    print(f"已重命名文件夹: {old_path} -> {new_path}")
                    found_and_renamed = True
                    
                    # 同时更新项目文件中的引用
                    update_file_references(project_path, old_name, new_name)
                except Exception as e:
                    print(f"重命名文件夹时出错: {e}")
    
    if not found_and_renamed:
        print(f"未找到名为 {old_name} 的文件或文件夹")
        return False
    
    return True

def update_file_references(project_path, old_name, new_name):
    """
    更新项目文件中对重命名文件的引用
    
    参数:
        project_path (str): 项目路径
        old_name (str): 旧文件名
        new_name (str): 新文件名
    """
    # 遍历项目文件
    for root, dirs, files in os.walk(project_path, topdown=True):
        dirs[:] = [d for d in dirs if isTrue(d)]
        files[:] = [f for f in files if (os.path.splitext(f)[1] in oc_yaml.list_support_open_file_type) or (f=='contents')]
        
        for name in files:
            file_path = os.path.join(root, name)
            try:
                with open(file_path, 'r', encoding='utf-8') as f:
                    file_content = f.read()
                
                # 检查文件是否包含对旧文件名的引用
                if old_name in file_content:
                    # 替换文件内容中的引用
                    modified_content = file_content.replace(old_name, new_name)
                    
                    # 如果内容有变化，写回文件
                    if modified_content != file_content:
                        with open(file_path, 'w', encoding='utf-8') as f:
                            f.write(modified_content)
                        print(f"已更新文件中的引用: {file_path}")
            except Exception as e:
                print(f"处理文件 {file_path} 时出错: {e}")


def delete_file_or_folder(path, recursive=True):
    """
    删除指定路径的文件或文件夹
    
    参数:
        path (str): 要删除的文件或文件夹的路径
        recursive (bool, optional): 如果是文件夹，是否递归删除其内容，默认为 True
    
    返回:
        bool: 操作成功返回 True，否则返回 False
    """
    import shutil
    
    try:
        if not os.path.exists(path):
            print(f"错误: 路径不存在: {path}")
            return False
            
        if os.path.isfile(path):
            # 删除文件
            os.remove(path)
            print(f"已删除文件: {path}")
        else:
            # 删除文件夹
            if recursive:
                shutil.rmtree(path)
                print(f"已递归删除文件夹: {path}")
            else:
                # 非递归删除只能删除空文件夹
                try:
                    os.rmdir(path)
                    print(f"已删除空文件夹: {path}")
                except OSError as e:
                    print(f"错误: 无法删除非空文件夹 {path}，请使用 recursive=True 参数")
                    return False
                    
        return True
    except Exception as e:
        print(f"删除 {path} 时出错: {e}")
        return False

def search_and_delete(base_path, pattern, file_only=False, folder_only=False, recursive=True, use_regex=False):
    """
    搜索并删除匹配指定模式的文件或文件夹
    
    参数:
        base_path (str): 搜索的基础路径
        pattern (str): 要匹配的模式，可以是文件名、扩展名或正则表达式
        file_only (bool, optional): 是否只删除文件，默认为 False
        folder_only (bool, optional): 是否只删除文件夹，默认为 False
        recursive (bool, optional): 是否递归搜索子文件夹，默认为 True
        use_regex (bool, optional): 是否使用正则表达式匹配，默认为 False
    
    返回:
        int: 成功删除的文件或文件夹数量
    """
    if not os.path.exists(base_path) or not os.path.isdir(base_path):
        print(f"错误: 基础路径不存在或不是文件夹: {base_path}")
        return 0
        
    # 如果同时指定了只删除文件和只删除文件夹，则报错
    if file_only and folder_only:
        print("错误: file_only 和 folder_only 不能同时为 True")
        return 0
        
    # 编译正则表达式（如果需要）
    if use_regex:
        try:
            pattern_regex = re.compile(pattern)
        except re.error as e:
            print(f"错误: 无效的正则表达式 '{pattern}': {e}")
            return 0
    
    deleted_count = 0
    
    # 遍历目录
    for root, dirs, files in os.walk(base_path, topdown=True):
        # 处理文件
        if not folder_only:
            for file in files:
                match = False
                if use_regex:
                    match = bool(pattern_regex.search(file))
                else:
                    match = pattern in file
                    
                if match:
                    file_path = os.path.join(root, file)
                    if delete_file_or_folder(file_path):
                        deleted_count += 1
        
        # 处理文件夹（注意：我们需要复制一份目录列表，因为我们可能会在循环中修改它）
        if not file_only:
            dirs_copy = dirs.copy()
            for dir_name in dirs_copy:
                match = False
                if use_regex:
                    match = bool(pattern_regex.search(dir_name))
                else:
                    match = pattern in dir_name
                    
                if match:
                    dir_path = os.path.join(root, dir_name)
                    if delete_file_or_folder(dir_path):
                        deleted_count += 1
                        # 从 dirs 列表中移除已删除的目录，防止 os.walk 继续尝试遍历它
                        if dir_name in dirs:
                            dirs.remove(dir_name)
        
        # 如果不是递归搜索，则在处理完第一级后退出
        if not recursive:
            break
    
    print(f"共删除了 {deleted_count} 个{'文件' if file_only else '文件夹' if folder_only else '文件或文件夹'}")
    return deleted_count

def delete_files_by_extension(base_path, extensions, recursive=True):
    """
    删除指定目录下具有特定扩展名的所有文件
    
    参数:
        base_path (str): 搜索的基础路径
        extensions (list): 要删除的文件扩展名列表，例如 ['.txt', '.log']
        recursive (bool, optional): 是否递归搜索子文件夹，默认为 True
    
    返回:
        int: 成功删除的文件数量
    """
    if not os.path.exists(base_path) or not os.path.isdir(base_path):
        print(f"错误: 基础路径不存在或不是文件夹: {base_path}")
        return 0
        
    # 确保扩展名列表中的每个项目都以点开头
    normalized_extensions = [ext if ext.startswith('.') else f'.{ext}' for ext in extensions]
    
    deleted_count = 0
    
    # 遍历目录
    for root, _, files in os.walk(base_path, topdown=True):
        for file in files:
            file_ext = os.path.splitext(file)[1].lower()
            if file_ext in normalized_extensions:
                file_path = os.path.join(root, file)
                if delete_file_or_folder(file_path):
                    deleted_count += 1
        
        # 如果不是递归搜索，则在处理完第一级后退出
        if not recursive:
            break
    
    print(f"共删除了 {deleted_count} 个文件")
    return deleted_count


def remove_project_from_workspace(workspace_path, project_name, project_path=None):
    """
    从 xcworkspace 中移除指定名字的工程
    
    参数:
        workspace_path (str): xcworkspace 文件的路径，例如 '/path/to/MyProject.xcworkspace'
        project_name (str): 要移除的工程名称，例如 'MyProject' 或 'MyProject.xcodeproj'
        project_path (str, optional): 项目路径，默认使用 oc_util.path_mix_project
    
    返回:
        bool: 操作成功返回 True，否则返回 False
    """
    import xml.etree.ElementTree as ET
    import os
    
    if not project_path:
        project_path = oc_util.path_mix_project
    
    # 确保工程名称包含 .xcodeproj 后缀
    if not project_name.endswith('.xcodeproj'):
        project_name = f"{project_name}.xcodeproj"
    
    # 检查 workspace 文件是否存在
    if not os.path.exists(workspace_path) or not os.path.isdir(workspace_path):
        print(f"错误: workspace 路径不存在或不是文件夹: {workspace_path}")
        return False
    
    # 构建 contents.xcworkspacedata 文件路径
    contents_path = os.path.join(workspace_path, "contents.xcworkspacedata")
    if not os.path.exists(contents_path):
        print(f"错误: workspace 内容文件不存在: {contents_path}")
        return False
    
    try:
        # 解析 XML 文件
        tree = ET.parse(contents_path)
        root = tree.getroot()
        
        # 查找所有 FileRef 元素
        file_refs = root.findall(".//FileRef")
        removed = False
        
        # 遍历所有 FileRef 元素，查找并移除包含指定工程名称的引用
        for file_ref in list(file_refs):  # 使用 list() 创建副本以便安全删除
            location = file_ref.get('location')
            if location and project_name in location:
                # 找到了目标工程，从其父元素中移除
                # 查找父元素
                parent = None
                for elem in root.iter():
                    for child in list(elem):
                        if child == file_ref:
                            parent = elem
                            break
                    if parent:
                        break
                
                if parent is not None:
                    parent.remove(file_ref)
                    removed = True
                    print(f"已从 workspace 中移除工程: {project_name}")
        
        if not removed:
            print(f"未在 workspace 中找到工程: {project_name}")
            return False
        
        # 保存修改后的 XML 文件
        tree.write(contents_path, encoding="utf-8", xml_declaration=True)
        return True
    
    except Exception as e:
        print(f"从 workspace 中移除工程时出错: {e}")
        return False

# 命令行接口
if __name__ == "__main__":
    import sys
    
    if len(sys.argv) < 3:
        print("用法: python -m ObjectiveC.oc_custom.custom_file remove_workspace_project <workspace_path> <project_name>")
        sys.exit(1)
    
    command = sys.argv[1]
    
    if command == "remove_workspace_project":
        if len(sys.argv) < 4:
            print("错误: 缺少参数!")
            print("用法: python -m ObjectiveC.oc_custom.custom_file remove_workspace_project <workspace_path> <project_name>")
            sys.exit(1)
        
        workspace_path = sys.argv[2]
        project_name = sys.argv[3]
        
        success = remove_project_from_workspace(workspace_path, project_name)
        if not success:
            sys.exit(1)