import subprocess
import os
import logging
import sys
import re
g_percentage_msg = None
g_has_error = False



def run_grep_command(grep_command_obj, filepath):
    """使用自定义的grep命令从文件中提取数字，并返回数字列表。"""
    try:
        grep_command = grep_command_obj["cmd"]
        # 构建完整的grep命令
        command = f"cat {filepath} | {grep_command} "
        print(command)
        # 运行命令并捕获输出
        result = subprocess.run(command, shell=True, text=True, capture_output=True)
        # 提取输出中的数字
        numbers = list()
        for line in result.stdout.splitlines():
            matches = re.findall(r'[0-9]+(?:\.[0-9]+)?', line)
            numbers.extend([float(match) for match in matches])
        return numbers
    except Exception as e:
        print(f"Error running grep command: {e}")
        return []

def compare_numbers(numbers1, numbers2, threshold=0.05):
    """比较两个数字列表，检查差异是否都在阈值以内。"""
    print(numbers1, numbers2)
    if len(numbers1) != len(numbers2):
        return False
    for num1, num2 in zip(numbers1, numbers2):
        if  max(num1, num2) == 0:
            if num1 != num2:
                return False
            else:
                continue
        if abs(num1 - num2) / max(num1, num2) > threshold:
            print("not within threshold {} {}".format(num1, num2))
            percentage = abs(num1 - num2) / max(num1, num2)
            print(f"percentage: {percentage}")
            g_percentage_msg = f"偏移: {percentage}"
            return False
    return True

"""比较两个数字列表，检查差异是否大于"""
def compare_numbers_greater(numbers1, numbers2):
    """比较两个数字列表，检查差异是否大于阈值。"""
    if len(numbers1) != len(numbers2):
        return False
    for num1, num2 in zip(numbers1, numbers2):
        if num1 < num2:
            print("not greater {} {}".format(num1, num2))
            percentage = abs(num1 - num2) / max(num1, num2)
            print(f"percentage: {percentage}")
            g_percentage_msg = f"偏移: {percentage}"
            return False
    return True

def compare_numbers_with_tolerance_greater(numbers1, numbers2, tolerance=0.05):
    """
    比较两个数字列表，检查第一个列表的元素是否大于第二个列表的对应元素。
    如果不大于，但差异在容忍的百分比内，也认为通过。
    参数：
    - numbers1: 第一个数字列表。
    - numbers2: 第二个数字列表。
    - tolerance: 容忍的百分比。
    返回：
    - True 如果所有比较都通过，否则 False。
    """
    if len(numbers1) != len(numbers2):
        return False
    for num1, num2 in zip(numbers1, numbers2):
        if num1 < num2:
            diff = abs(num1 - num2)
            if num2 != 0 and (diff / num2) > tolerance:
                print(f"不通过: {num1} < {num2}, 差异百分比: {diff / num2:.2%} 超过容忍值: {tolerance:.2%}")
                return False
            else:
                #print(f"通过: {num1} < {num2}, 但差异百分比: {diff / num2:.2%} 在容忍值: {tolerance:.2%} 内")
                pass
        else:
            #print(f"通过: {num1} >= {num2}")
            pass
    return True


"""比较两个数字列表，检查是否小于"""
def compare_numbers_less(numbers1, numbers2):
    """比较两个数字列表，检查差异是否小于阈值。"""
    if len(numbers1) != len(numbers2):
        return False
    for num1, num2 in zip(numbers1, numbers2):
        if num1 > num2:
            print("not less {} {}".format(num1, num2))
            percentage = abs(num1 - num2) / max(num1, num2)
            print(f"percentage: {percentage}")
            g_percentage_msg = f"偏移: {percentage}"
            return False
    return True

def compare_numbers_with_tolerance_less(numbers1, numbers2, tolerance=0.05):
    """
    比较两个数字列表，检查第一个列表的元素是否小于第二个列表的对应元素。
    如果不小于，但差异在容忍的百分比内，也认为通过。
    参数：
    - numbers1: 第一个数字列表。
    - numbers2: 第二个数字列表。
    - tolerance: 容忍的百分比。
    返回：
    - True 如果所有比较都通过，否则 False。
    """
    if len(numbers1) != len(numbers2):
        return False
    for num1, num2 in zip(numbers1, numbers2):
        if num1 > num2:
            diff = abs(num1 - num2)
            if num2 != 0 and (diff / num2) > tolerance:
                print(f"不通过: {num1} > {num2}, 差异百分比: {diff / num2:.2%} 超过容忍值: {tolerance:.2%}")
                return False
            else:
                #print(f"通过: {num1} > {num2}, 但差异百分比: {diff / num2:.2%} 在容忍值: {tolerance:.2%} 内")
                pass
        else:
            #print(f"通过: {num1} <= {num2}")
            pass
    return True

def compare_files(log_files, answer_files, grep_commands, result_file):
    """使用自定义的grep命令比较多组日志文件和答案文件，将结果写入结果文件。"""
    g_has_error = False
    common_file_prefix = '/root/presurelog/'
    ans_file_prefix = '/root/presure-test-tool/targetlog/'
    with open(result_file, 'w') as result:
        for log_file, answer_file, grep_command in zip(log_files, answer_files, grep_commands):
            try:
                log_numbers = run_grep_command(grep_command, common_file_prefix+log_file)
                answer_numbers = run_grep_command(grep_command, ans_file_prefix+answer_file)
                print('start diff %s and %s' % (log_file, answer_file))
                if grep_command['comparison'] == 'within_percentage':
                    is_normal = compare_numbers(log_numbers, answer_numbers, threshold=grep_command['percentage'])
                elif grep_command['comparison'] == 'less':
                    is_normal = compare_numbers_with_tolerance_less(log_numbers, answer_numbers, tolerance=grep_command['percentage'])
                elif grep_command['comparison'] == 'greater':
                    is_normal = compare_numbers_with_tolerance_greater(log_numbers, answer_numbers, tolerance=grep_command['percentage'])
                
                # add log
                if not is_normal:
                    print(f"{os.path.basename(log_file)}: 异常")
                    print(g_percentage_msg)
                else:
                    print(f"{os.path.basename(log_file)}: 正常")
                print(log_numbers)
                print(answer_numbers)
                diff_result = "正常" if is_normal else "异常"
                if diff_result == "异常":
                    g_has_error = True

                final_str = os.path.basename(log_file)+ " " + diff_result + "\n"
                result.write(final_str)
            except Exception as e:
                logging.error(f"Error comparing {log_file} and {answer_file}: {e}")
    return g_has_error


# 示例文件路径列表和对应的grep命令

analysis_config = {

    "check_list": [
        { 
            "file":"test_all_reduce_perf.log",  "cmd": "grep float| grep -Eo '[0-9]+(\.[0-9]+)?'  ", "comparison": "greater", "percentage": 0.05
        },
        #{  
        #    "file":"test_cpu.log",  "cmd": "grep total ", "comparison": "greater", "percentage": 0.05
        #},
        {  
            "file":"test_fio.log",   "cmd": "grep IOPS  | awk -F'/' '{print $1" "$2}' ", "comparison": "greater", "percentage": 0.05
        },
        {  
            "file":"test_gpu.log",   "cmd": "grep -Eo '[0-9]+(\.[0-9]+)?'", "comparison": "greater", "percentage": 0.10
        },
        {  
            "file":"test_mlc_latency_matrix.log",   "cmd": "grep -Eo '[0-9]+(\.[0-9]+)?'", "comparison": "less", "percentage": 0.05
        },
        {  
            "file":"test_mlc_max_bandwidth.log",   "cmd": "grep -Eo '[0-9]+(\.[0-9]+)?'", "comparison": "greater", "percentage": 0.05
        },
        {   
            "file":"test_pcie_p2p.log",    "cmd": "grep SUM ", "comparison": "greater", "percentage": 0.05
        },
    ],
    "result_file": '/root/comparison_pressure_result.txt'

}
'''
analysis_config = {

    "check_list": [
        #{ 
        #    "file":"test_all_reduce_perf.log",  "cmd": "grep -Eo '[0-9]+(\.[0-9]+)?'", "comparison": "greater", "percentage": 0.05
        #},
        {  
            "file":"test_cpu.log",  "cmd": "grep total ", "comparison": "within_percentage", "percentage": 0.1
        },
        #{  
        #    "file":"test_fio.log",   "cmd": "grep IOPS  | awk -F'/' '{print $1" "$2}' ", "comparison": "greater", "percentage": 0.05
        #},
        {  
            "file":"test_gpu.log",   "cmd": "grep -Eo '[0-9]+(\.[0-9]+)?'", "comparison": "within_percentage", "percentage": 0.1
        },
        {  
            "file":"test_mlc_latency_matrix.log",   "cmd": "grep -Eo '[0-9]+(\.[0-9]+)?'", "comparison": "within_percentage", "percentage": 0.1
        },
        {  
            "file":"test_mlc_max_bandwidth.log",   "cmd": "grep -Eo '[0-9]+(\.[0-9]+)?'", "comparison": "within_percentage", "percentage": 0.1
        },
        {   
            "file":"test_pcie_p2p.log",    "cmd": "grep SUM ", "comparison": "within_percentage", "percentage": 0.1
        },
    ],
    "result_file": '/root/comparison_pressure_result.txt'

}
'''





 # 日志文件路径列表

log_files = list()
for e_config in analysis_config['check_list']:
    log_files.append(e_config['file'])

 # 答案文件路径列表
answer_files = log_files

#    "grep -Eo '[0-9]+(\.[0-9]+)?'",  # 对第一对文件使用的grep命令
#    "grep -Eo '[0-9]+'",  # 对第二对文件使用的grep命令（仅匹配整数）
grep_commands = analysis_config['check_list']
result_file = analysis_config['result_file']

# 运行比较
ret = compare_files(log_files, answer_files, grep_commands, result_file)

# run cat /root/comparison_pressure_result.txt
command = "cat /root/comparison_pressure_result.txt"
result = subprocess.run(command, shell=True, text=True, capture_output=True)
print(result.stdout)

if ret:
    print("有异常的压测结果")
    sys.exit(1)
