"""
通用方法
"""
import random, re, os, shutil
from ObjectiveC import oc_util
from ObjectiveC import oc_yaml
from pbxproj import XcodeProject

def init():
    # 忽略日志
    global ignore_log_manager
    ignore_log_manager = get_ignore_log_manager()
def get_ignore_log_manager():
    return open(oc_util.path_mix + "/被忽略的关键词日志" + ".txt", "a+")
def random_one_string(num, isFirst):
    ''' 根据长度随机一个字符串\n isFirst=True,表示第一个首字母大写,False表示小写\n'''
    if num <= 3:
        num_list = ['3']
        num_string = random.choice(num_list)
        return get_unique_string(num_string, isFirst)
    elif num == 4:
        num_list = ['4']
        num_string = random.choice(num_list)
        return get_unique_string(num_string, isFirst)
    elif num == 5:
        num_list = ['5']
        num_string = random.choice(num_list)
        return get_unique_string(num_string, isFirst)
    elif num == 6:
        num_list = ['6','33']
        num_string = random.choice(num_list)
        return get_unique_string(num_string, isFirst)
    elif num == 7:
        num_list = ['7','34','43']
        num_string = random.choice(num_list)
        return get_unique_string(num_string, isFirst)
    elif num == 8:
        # (8)(3,5)(5,3)(4,4)
        num_list = ['8','53','35','44']
        num_string = random.choice(num_list)
        return get_unique_string(num_string, isFirst)
    elif num == 9:
        # (9)(6,3)(3,6)(5,4)(4,5)
        num_list = ['9','63','36','54','45']
        num_string = random.choice(num_list)
        return get_unique_string(num_string, isFirst)
    elif num == 10:
        num_list = ['73','37','46','64','55','433','343','334']
        num_string = random.choice(num_list)
        return get_unique_string(num_string, isFirst)
    elif num == 11: 
        num_list = ['83','38','47','74','56','65','335','353','533','443','434','344']
        num_string = random.choice(num_list)
        return get_unique_string(num_string, isFirst)
    elif num == 12:
        num_list = ['93','39','84','48','75','57','66','336','363','633','345','354','543','534','435','453']
        num_string = random.choice(num_list)
        return get_unique_string(num_string, isFirst)
    elif num == 13:
        num_list = ['94','49','85','58','67','76','445','454','544','355','535','553','337','373','3433','4333','3343','3334']
        num_string = random.choice(num_list)
        return get_unique_string(num_string, isFirst)
    elif num == 14:
        num_list = ['95','59','68','86','77','455','545','554','446','464','644','3344','3434','3443','4433','4343','4334','3335','3353','3533','5333']
        num_string = random.choice(num_list)
        return get_unique_string(num_string, isFirst)
    elif num>=15 and num<20:
        num_string = ''
        aList = ['3','4','5','6','7','8','9']
        for _ in range(5):
            num_string = num_string + random.choice(aList)
        return get_unique_string(num_string, isFirst)
    elif num>=20 and num<30:
        num_string = ''
        aList = ['3','4','5','6','7','8','9']
        for _ in range(6):
            num_string = num_string + random.choice(aList)
        return get_unique_string(num_string, isFirst)
    elif num>=30 and num<40:
        num_string = ''
        aList = ['3','4','5','6','7','8','9']
        for _ in range(7):
            num_string = num_string + random.choice(aList)
        return get_unique_string(num_string, isFirst)
    elif num>=40 and num<50:
        num_string = ''
        aList = ['3','4','5','6','7','8','9']
        for _ in range(8):
            num_string = num_string + random.choice(aList)
        return get_unique_string(num_string, isFirst)
    else:
        num_string = ''
        aList = ['3','4','5','6','7','8','9']
        for _ in range(9,12):
            num_string = num_string + random.choice(aList)
        return get_unique_string(num_string, isFirst)
def get_unique_string(num_string, isFirst):
    name = ''
    isOne = isFirst
    for num in num_string:
        if num == '3':
            name = name + oc_util.three().capitalize()
        elif num == '4':
            name = name + oc_util.four().capitalize()
        elif num == '5':
            name = name + oc_util.five().capitalize()
        elif num == '6':
            name = name + oc_util.six().capitalize()
        elif num == '7':
            name = name + oc_util.seven().capitalize()
        elif num == '8':
            name = name + oc_util.eight().capitalize()
        elif num == '9':
            name = name + oc_util.nine().capitalize()
        if isOne==False:
            name = name.lower()
            isOne = True
    return name

def isHasLetterNumXia(string):
    ''' 字符串是否由数字字母合下划线组合而成 '''
    if re.match("^[A-Za-z0-9_]*$", string):
        return True
    return False

def is_word_can_mix(descripe, old_name):
    ''' 关键词是否允许被混淆 False不允许 True允许'''
    # 关键词为空
    if len(old_name)==0 or old_name.isspace():
        return False
    # 关键词不是字母数字下划线的组合 
    if isHasLetterNumXia(old_name)==False:
        return False
    # 关键词在被忽略列表中
    if old_name in oc_util.list_ignore_keyword:
        return False
    # 用户自定义不可修改关键词
    if old_name in oc_yaml.list_user_custom_keyword_not_change:
        oc_util.list_ignore_keyword.append(old_name)
        return False
    if old_name in oc_util.list_system_framework_word:
        ignore_log_manager.write('%s-系统framework包含关键词:%s\n'%(descripe, old_name))
        oc_util.list_ignore_keyword.append(old_name)
        return False
    if old_name in oc_util.list_project_framework_word:
        ignore_log_manager.write('%s-工程framework包含关键词:%s\n'%(descripe, old_name))
        oc_util.list_ignore_keyword.append(old_name)
        return False
    # 关键词和文件名重复
    if old_name in oc_util.class_oc_file.all_file_name_list:
        ignore_log_manager.write('%s-总文件名列表含关键词:%s\n'%(descripe, old_name))
        oc_util.list_ignore_keyword.append(old_name)
        return False
    # 在字符串中且用户没有允许修改
    if (old_name in oc_util.list_string_words) and (old_name not in oc_yaml.list_user_arrow_change_keyword):
        ignore_log_manager.write('%s-字符串含关键词:%s\n'%(descripe, old_name))
        oc_util.list_ignore_keyword.append(old_name)
        return False
    # 在总表中
    if old_name in oc_util.class_oc_file.total_words:
        ignore_log_manager.write('%s-总表中含关键词:%s\n'%(descripe, old_name))
        oc_util.list_ignore_keyword.append(old_name)
        return False
    return True
def is_name_legal(new_name):
    ''' 混淆前后关键词是否合法 '''
    # 关键词为空
    if len(new_name)==0 or new_name.isspace():
        return False
    # 关键词不是字母数字下划线的组合 
    if isHasLetterNumXia(new_name)==False:
        return False
    # 文件名列表
    if new_name in oc_util.class_oc_file.all_file_name_list:
        return False
    # 关键词在被忽略列表中
    if new_name in oc_util.list_ignore_keyword:
        return False
    # 用户自定义不可修改关键词
    if new_name in oc_yaml.list_user_custom_keyword_not_change:
        return False
    # 关键词和文件名重复
    if new_name in oc_util.class_oc_file.all_file_name_list:
        return False
    # 在字符串中且用户没有允许修改
    if (new_name in oc_util.list_string_words) and (new_name not in oc_yaml.list_user_arrow_change_keyword):
        return False
    # 在总表中
    if new_name in oc_util.class_oc_file.total_words:
        return False
    # 系统关键词
    if new_name in oc_util.list_system_framework_word:
        return False
    # 工程关键词
    if new_name in oc_util.list_project_framework_word:
        return False
    return True
def add_group(g_name, g_parent):
    ''' 
    创建group for xcodeproj\n
    g_name: group名\n
    g_parent: group在哪个group的下面,父类group名
    '''
    proj_path = '%s/%s.xcodeproj/project.pbxproj'%(oc_util.path_mix_project,oc_util.name_current_project)
    hs_project = XcodeProject.load(proj_path)
    p_parent = hs_project.get_groups_by_name(g_parent)[0]
    hs_project.add_group(name=g_name, parent=p_parent)
    # 备份
    # backname =  hs_project.backup()
    # print(backname)
    hs_project.save(proj_path)
def add_file(f_parent, f_path):
    ''' 
    添加文件到group 
    param: f_parent: 存放文件夹名
    param: f_path: 文件存放路径
    '''
    proj_path = '%s/%s.xcodeproj/project.pbxproj'%(oc_util.path_mix_project,oc_util.name_current_project)
    hs_project = XcodeProject.load(proj_path)
    p_parent = hs_project.get_groups_by_name(f_parent)[0]
    hs_project.add_file(path=f_path, parent=p_parent, force=False)
    # 备份
    # backname =  hs_project.backup()
    # print(backname)
    hs_project.save(proj_path)

def get_current_mix_path(date_dir,input_path):
    '''
    获取当前混淆目录
    '''
    if os.path.exists(input_path)==False or os.path.isdir(input_path)==False:
        # 在打包环境中不使用交互式输入
        import sys
        if hasattr(sys, '_MEIPASS'):
            raise ValueError(f"输入路径无效或不存在: {input_path}")
        else:
            input_path = input("\n输入路径有误,请确认后重新输入:")
            return get_current_mix_path(date_dir, input_path)
    
    # 获取正确的基础路径
    import sys
    if hasattr(sys, '_MEIPASS'):
        # PyInstaller打包环境，使用用户主目录
        base_path = os.path.expanduser("~")
        print(f"打包环境，使用用户目录: {base_path}")
    else:
        # 开发环境，获取项目根目录
        current_file = os.path.abspath(__file__)
        base_path = os.path.dirname(os.path.dirname(current_file))
        print(f"开发环境，使用项目目录: {base_path}")
    
    # 确保混淆目录存在
    mix_base_dir = os.path.join(base_path, "混淆完成后的文件")
    print(f"混淆基础目录: {mix_base_dir}")
    
    try:
        if not os.path.exists(mix_base_dir):
            os.makedirs(mix_base_dir, exist_ok=True)
            print(f"创建混淆基础目录成功")
    except Exception as e:
        print(f"创建混淆基础目录失败: {e}")
        raise
    
    # 创建日期目录
    date_dir_path = os.path.join(mix_base_dir, date_dir)
    print(f"日期目录路径: {date_dir_path}")
    
    try:
        if not os.path.exists(date_dir_path):
            os.makedirs(date_dir_path, exist_ok=True)
            print(f"创建日期目录成功")
    except Exception as e:
        print(f"创建日期目录失败: {e}")
        raise
    
    new_path = os.path.join(date_dir_path, "混淆后工程")
    print(f"正在复制工程到: {new_path}")
    
    # 复制工程到混淆目录，忽略.git文件夹
    try:
        shutil.copytree(input_path, new_path, ignore=shutil.ignore_patterns('.git', '.git*' ,'Pods', 'build', '.vscode'))
        print(f"工程复制完成")
    except Exception as e:
        print(f"复制工程失败: {e}")
        raise
    
    return date_dir_path

def get_current_project_name(name=None):
    ''' 
    获取当前工程名 
    参数:
        name: 可选，指定工程名称，如果提供则直接返回
    返回:
        工程名称
    '''
    if name:
        return name
        
    p_name = ''
    path = oc_util.path_mix_project
    print(f"正在搜索项目文件，路径: {path}")
    
    xcodeproj_files = []
    for _, dirs, _ in os.walk(path, topdown=True):
        for dir_name in dirs:
            if dir_name.endswith('.xcodeproj'):
                xcodeproj_files.append(dir_name)
                project_name = os.path.splitext(dir_name)[0]
                if project_name not in oc_yaml.list_filter_project:
                    p_name = project_name
                    print(f"找到项目文件: {dir_name}, 项目名称: {p_name}")
                    break
    
    if not p_name:
        if xcodeproj_files:
            print(f"警告: 找到的所有项目文件都在过滤列表中: {xcodeproj_files}")
        else:
            print(f"错误: 在路径 {path} 中没有找到任何 .xcodeproj 文件")
            # 如果没有找到任何项目文件，可以尝试使用目录名作为项目名
            p_name = os.path.basename(path)
            print(f"使用目录名作为项目名: {p_name}")
    
    return p_name

