"""
属性 、函数声明、 函数实现位置随机调换
"""
from ObjectiveC import oc_util
from ObjectiveC import oc_yaml
from ObjectiveC.oc_function import e_print_annotation
import os, re, random

def init():
    path = oc_util.path_mix_project
    open_file_and_move_location(path)
def open_file_and_move_location(path):
    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]
        for name in files:
            if name in ['GCDAsyncSocket.h', 'GCDAsyncSocket.m', 'WebSocket.h','WebSocket.m']:
                continue
            file_path = os.path.join(root, name)
            with open(file_path, 'r') as f:
                file_content = f.read()
                file_content = e_print_annotation.search_annotation_and_delete(file_content)
                file_content = e_print_annotation.search_print_and_delete(file_content)
                file_content = search_property_and_move(file_content)
                file_content = search_method_header_and_move(file_content)
                file_content = search_method_imp_and_move(file_content)
            with open(file_path, 'w') as f:
                f.write(file_content)
def isTrue(d):
    return (d.endswith('.xcodeproj')==False) and (d.endswith('.framework')==False)
def search_property_and_move(file_content):
    ''' 搜索属性并进行位置替换 '''
    p1 = re.compile(r'(@interface)(.*?)(@end)', re.S)
    a_list = p1.findall(file_content)
    for a in a_list:
        # 当前操作内容
        a_str = ''.join(a)
        property_list = [] # 存放属性语句的列表
        # 如果含有#if的情况
        if a_str.count('#if') > 0:
            p3 = re.compile(r'(#if)(.*?)(#endif)', re.S)
            c_list = p3.findall(a_str)
            for c in c_list:
                c_str = ''.join(c)
                # 判断#if里面是否有完整的属性
                c_str = remove_symbol(c_str)
                px = re.compile(r'(@property)(.*?)(;)')
                x_list = px.findall(c_str)
                if len(x_list)>0:
                    property_list.append(c_str)
                    a_str = a_str.replace(c_str, '\n', 1)
        p2 = re.compile(r'(@property)(.*?)(;)')
        b_list = p2.findall(a_str)
        for b in b_list:
            b_str = ''.join(b)
            property_list.append(b_str)
        list_len = len(property_list)
        if list_len <= 1:
            continue
        # 拿到所有属性语句之后,对其进行随机调换
        num_list = []
        op_a = ''.join(a)
        for x in range(list_len):
            num_list.append(x)
        for index in range(list_len):
            one_num = random.choice(num_list)
            num_list.remove(one_num)
            temp_str = 'property_cccc_yyyy_llll' + str(one_num).zfill(3)
            op_a = op_a.replace(property_list[index], temp_str, 1)
        for index in range(list_len):
            temp_str = 'property_cccc_yyyy_llll' + str(index).zfill(3)
            tap_num = random.randint(1,100)
            tap_text = '\n' if tap_num%6==0 else ''
            new_str = property_list[index] + tap_text
            op_a = op_a.replace(temp_str, new_str, 1)
        file_content = file_content.replace(''.join(a), op_a, 1)
    return file_content
def search_method_header_and_move(file_content):
    ''' 搜索方法声明并替换 '''
    p1 = re.compile(r'(@interface)(.*?)(@end)', re.S)
    a_list = p1.findall(file_content)
    for a in a_list:
        # 当前操作内容
        a_str = ''.join(a)
        method_header_list = [] # 存放属性语句的列表
        # 如果含有#if的情况
        if a_str.count('#if') > 0:
            p3 = re.compile(r'(#if)(.*?)(#endif)', re.S)
            c_list = p3.findall(a_str)
            for c in c_list:
                c_str = ''.join(c)
                # 判断#if里面是否有完整的函数声明
                c_str = remove_symbol(c_str)
                px = re.compile(r'(-|\+)( {0,})(\()(.*?)(\))(.*?)( {0,})(;)', re.S)
                x_list = px.findall(c_str)
                if len(x_list)>0:
                    method_header_list.append(c_str)
                    a_str = a_str.replace(c_str, '\n', 1)
        p2 = re.compile(r'(-|\+)( {0,})(\()(.*?)(\))(.*?)(;)', re.S)
        b_list = p2.findall(a_str)
        for b in b_list:
            b_str = ''.join(b)
            method_header_list.append(b_str)
        list_len = len(method_header_list)
        if list_len <= 1:
            continue
        # 拿到所有属性语句之后,对其进行随机调换
        num_list = []
        op_a = ''.join(a)
        for x in range(list_len):
            num_list.append(x)
        for index in range(list_len):
            one_num = random.choice(num_list)
            num_list.remove(one_num)
            temp_str = 'header_cccc_yyyy_llll' + str(one_num).zfill(3)
            op_a = op_a.replace(method_header_list[index], temp_str, 1)
        for index in range(list_len):
            temp_str = 'header_cccc_yyyy_llll' + str(index).zfill(3)
            tap_num = random.randint(1,100)
            tap_text = '\n' if tap_num%6==0 else ''
            new_str = method_header_list[index] + tap_text
            op_a = op_a.replace(temp_str, new_str, 1)
        file_content = file_content.replace(''.join(a), op_a, 1)
    return file_content
def search_method_imp_and_move(file_content):
    ''' 调换函数实现 '''
    p1 = re.compile(r'(@implementation)(.*?)(@end)', re.S)
    a_list = p1.findall(file_content)
    for a in a_list:
        a_str = ''.join(a)
        method_imp_list = []
        if_list = []
        # 先拿#if #endif的函数, 放到函数实现列表中
        p2 = re.compile(r'(#if)(.*?)(#endif)',re.S)
        b_list = p2.findall(a_str)
        for b in b_list:
            b_str = ''.join(b[1])
            b_str = b_str.strip()
            # 判断里面是否有完整的函数
            b_str = remove_symbol(b_str)
            px = re.compile(r'(-|\+)( {0,})(\()(.*?)(\))(.*?)( {0,})(;)', re.S)
            x_list = px.findall(b_str)
            if len(x_list)>0:
                if_list.append(''.join(b))
                a_str = a_str.replace(''.join(b), '\n', 1)
        # 取其他函数实现
        a_str = remove_symbol(a_str)
        p3 = re.compile(r'(-|\+)( {0,})(\()(.*?)(\))(.*?)( {0,})(;)', re.S)
        c_list = p3.findall(a_str)
        old_method_list = []
        temp_method_list = []
        a_str = ''.join(a)
        for name in method_imp_list:
            a_str = a_str.replace(name, '\n', 1)
        for index in range(len(c_list)):
            c = c_list[index]
            # 函数名
            method_name = ''.join(c[:-1])
            temp_name = 'temp_cccc_yyyy_llll' + str(index).zfill(3)
            a_str = a_str.replace(method_name, temp_name, 1)
            old_method_list.append(method_name)
            temp_method_list.append(temp_name)
        old_list_len = len(old_method_list)
        for index in range(old_list_len):
            first = temp_method_list[index]
            second = ''
            if index == old_list_len-1:
                second = '@end'
            else:
                second = temp_method_list[index+1]
            p4 = re.compile(r'(%s)({)(.*)(})(.*)(%s)'%(first,second), re.S)
            d_list = p4.findall(a_str)
            for d in d_list:
                method = ''.join(d[:-1])
                method_imp_list.append(method)
        # 还原
        for index in range(len(temp_method_list)):
            old_text = old_method_list[index]
            temp_text = temp_method_list[index]
            origin_value = method_imp_list[index]
            origin_value = origin_value.replace(temp_text, old_text, 1)
            a_str = a_str.replace(temp_text, old_text, 1)
            method_imp_list[index] = origin_value
        # print(if_list)
        # print('\n---------------------------------------------\n')
        # method_imp_list = method_imp_list + if_list
        # 小于两个不切换
        if len(method_imp_list) <= 1:
            continue
        # 拿到所有函数实现之后, 开始调换
        method_len = len(method_imp_list)
        num_list =[]
        a_str = ''.join(a)
        for x in range(method_len):
            num_list.append(x)
        for index in range(method_len):
            one_num = random.choice(num_list)
            num_list.remove(one_num)
            temp_str = 'imp_cccc_yyyy_llll' + str(one_num).zfill(3)
            a_str = a_str.replace(method_imp_list[index], temp_str, 1)
        for index in range(method_len):
            old_text = 'imp_cccc_yyyy_llll' + str(index).zfill(3)
            tap_num = random.randint(1,100)
            tap_text = '\n' if tap_num%6==0 else ''
            new_text = method_imp_list[index] + tap_text
            a_str = a_str.replace(old_text, new_text, 1)
        file_content = file_content.replace(''.join(a), a_str, 1)
    return file_content
# 去掉所有大括号和里面的内容,改为分号
def remove_symbol(string):
    p1 = re.compile(r'{([^\{\}]*?)}', re.S)
    aList = p1.findall(string)
    for a in aList:
        a = '{' + a + '}'
        string = string.replace(a,';')
    if string.count('{')>0 or string.count('}')>0:
        return remove_symbol(string)
    return string