import sys
import os
import tempfile
import shutil
from pathlib import Path

sys.path.append(os.path.join(os.path.dirname(__file__), '..'))
from utils.utils import DefconfigParser

def test_defconfig_parser_read():
    """测试 DefconfigParser 类的读取功能"""
    defconfig_path = os.path.join(os.path.dirname(__file__), 'data', 'test_defconfig')
    parser = DefconfigParser(defconfig_path)
    temp_file1 = os.path.join(os.path.dirname(__file__), '.tmp', 'test_defconfig_parsed.json')
    with open(temp_file1, 'w') as f:
        f.write(f"{parser}")
    # 测试获取简单键值对
    assert parser.get('CONFIG_SIMPLE') == 'y'
    assert parser['CONFIG_SIMPLE'] == 'y' # 使用索引方式访问
    assert parser.get('CONFIG_WITH_SPACES') == 'y'
    assert parser.get('CONFIG_NO_SPACES') == 'y'
    
    # 测试获取数值配置
    assert parser.get('CONFIG_INT_VALUE') == '100'
    assert parser.get('CONFIG_HEX_VALUE') == '0x1000'
    assert parser.get('CONFIG_OCTAL_VALUE') == '0755'
    
    # 测试获取字符串配置
    assert parser.get('CONFIG_STRING') == '"hello world"'
    assert parser.get('CONFIG_STRING_NO_QUOTES') == 'hello world'
    
    # 测试获取特殊字符配置
    assert parser.get('CONFIG_PATH') == '/usr/local/bin:/usr/bin:/bin'
    assert parser.get('CONFIG_SPECIAL_CHARS') == '$HOME/.config'
    
    # 测试带有注释的配置
    assert parser.get('CONFIG_WITH_COMMENT') == 'y'
    
    # 测试混合格式
    assert parser.get('CONFIG_MIXED') == '"value with spaces"'
    
    # 测试空值配置
    assert parser.get('CONFIG_EMPTY') == ''
    
    # 测试布尔值配置
    assert parser.get('CONFIG_BOOL_TRUE') == 'y'
    assert parser.get('CONFIG_BOOL_FALSE') == 'n'
    
    # 测试多行内容配置 (在实际解析中可能会有所不同，取决于实现)
    multiline_value = parser.get('CONFIG_MULTILINE')
    assert 'first line' in multiline_value
    
    # 测试含有等号的值
    assert parser.get('CONFIG_WITH_EQUAL') == 'key=value'
    
    # 测试重复的键 (应该获取最后一个值)
    assert parser.get('CONFIG_DUPLICATE') == 'second'
    
    # 测试长路径配置
    assert '/very/long/path' in parser.get('CONFIG_LONG_PATH')
    
    # 测试不存在的键
    assert parser.get('CONFIG_NOT_EXIST', 'default') == 'default'

def test_defconfig_parser_rw():
    """测试 DefconfigParser 类的读写功能，看是否能够正确写回文件"""
    src_file = os.path.join(os.path.dirname(__file__), 'data', 'test_defconfig')
    parser = DefconfigParser(src_file)
    temp_dir = tempfile.mkdtemp()
    if 1:
        new_file = os.path.join(os.path.dirname(__file__), '.tmp', 'test_defconfig_copy')
    else:
        new_file = os.path.join(temp_dir, 'test_defconfig_copy')
    # temp_file1 = os.path.join(os.path.dirname(__file__), 'test_defconfig_parsed.json')
    # with open(temp_file1, 'w') as f:
    #     f.write(f"{parser}")
    parser.flush(new_file)
    try:
        with open(new_file, 'r') as f:
            with open(src_file, 'r') as f2:
                # 由于一些格式控制符，导致读取的文件与原文件不一致，这里忽略空格进行比较
                src = f2.read().replace(' ', '')
                dst = f.read().replace(' ', '')
                assert src == dst
    finally:
        # 清理临时文件
        if os.path.exists(temp_dir):
            shutil.rmtree(temp_dir)


def test_defconfig_parser_modify():
    """测试 DefconfigParser 类的修改功能"""
    # 创建测试文件的副本
    temp_dir = tempfile.mkdtemp()
    temp_file = os.path.join(temp_dir, 'test_defconfig_copy')
    original_file = os.path.join(os.path.dirname(__file__), 'data', 'test_defconfig')
    shutil.copy(original_file, temp_file)
    
    try:
        parser = DefconfigParser(temp_file)
        
        # 修改现有配置
        parser['CONFIG_SIMPLE'] = 'n'
        parser['CONFIG_INT_VALUE'] = '200'
        parser['CONFIG_STRING'] = '"modified string"'
        
        # 添加新配置
        parser['CONFIG_NEW'] = 'new_value'

        # 删除配置
        del parser['CONFIG_EMPTY']

        idx = parser.index('CONFIG_SIMPLE')
        parser.insert(idx, 'CONFIG_SIMPLE_NEW', '=', 'new_value_new')
        # 刷新到文件
        parser.flush()

        # temp_file1 = os.path.join(os.path.dirname(__file__), 'test_defconfig_parsed.json')
        # with open(temp_file1, 'w') as f:
        #     f.write(f"{parser}")

        # 重新加载验证修改
        new_parser = DefconfigParser(temp_file)
        assert new_parser.get('CONFIG_SIMPLE') == 'n'
        assert new_parser.get('CONFIG_INT_VALUE') == '200'
        assert new_parser.get('CONFIG_STRING') == '"modified string"'
        assert new_parser.get('CONFIG_NEW') == 'new_value'
        assert new_parser.get('CONFIG_EMPTY') is None # 删除的配置
        assert new_parser.get('CONFIG_SIMPLE_NEW') == 'new_value_new' # 插入的配置
    finally:
        # 清理临时文件
        if os.path.exists(temp_dir):
            shutil.rmtree(temp_dir)

def test_defconfig_parser_content_preservation():
    """测试 DefconfigParser 类是否保留原始文件的注释和结构"""
    # 创建测试文件的副本
    temp_dir = tempfile.mkdtemp()
    temp_file = os.path.join(temp_dir, 'test_defconfig_copy')
    original_file = os.path.join(os.path.dirname(__file__), 'data', 'test_defconfig')
    shutil.copy(original_file, temp_file)
    
    try:
        # 记录原始文件的行数和注释行数
        with open(temp_file, 'r') as f:
            original_lines = f.readlines()
            original_line_count = len(original_lines)
            original_comment_count = sum(1 for line in original_lines if line.strip().startswith('#'))
        
        # 进行一些简单修改
        parser = DefconfigParser(temp_file)
        parser['CONFIG_SIMPLE'] = 'n'
        parser.flush()
        
        # 检查修改后的文件结构是否保留
        with open(temp_file, 'r') as f:
            modified_lines = f.readlines()
            modified_line_count = len(modified_lines)
            modified_comment_count = sum(1 for line in modified_lines if line.strip().startswith('#'))
        
        # 行数应该大致相同
        assert abs(original_line_count - modified_line_count) < 5
        
        # 注释应该完全保留
        assert original_comment_count == modified_comment_count
    finally:
        # 清理临时文件
        if os.path.exists(temp_dir):
            shutil.rmtree(temp_dir)

def test_edge_cases():
    """测试 DefconfigParser 类的边缘情况处理"""
    # 创建一个临时的 defconfig 文件，包含一些边缘情况
    temp_dir = tempfile.mkdtemp()
    temp_file = os.path.join(temp_dir, 'edge_case_defconfig')
    
    try:
        # 创建一个包含边缘情况的 defconfig 文件
        with open(temp_file, 'w') as f:
            f.write("# 空文件开始\n\n")
            f.write("# 只有注释的行\n")
            f.write("CONFIG_NO_VALUE=\n")  # 无值
            f.write("CONFIG_SPACES_AROUND_EQUAL  =  value_with_spaces_around_equal\n")  # 等号周围有多个空格
            f.write("=invalid_line_no_key\n")  # 无效行，没有键
            f.write("invalid_line_no_equal\n")  # 无效行，没有等号
        
        # 解析文件并测试
        parser = DefconfigParser(temp_file)
        
        # 检查无值配置
        assert parser.get('CONFIG_NO_VALUE') == ''
        
        # 检查等号周围有多个空格的配置
        assert parser.get('CONFIG_SPACES_AROUND_EQUAL') == 'value_with_spaces_around_equal'
        
        # 检查无效行处理
        assert parser.get('invalid_line_no_equal', 'not_found') == 'not_found'
        
        # 修改并保存
        parser['CONFIG_NO_VALUE'] = 'now_has_value'
        parser.flush()
        
        # 重新加载并验证
        new_parser = DefconfigParser(temp_file)
        assert new_parser.get('CONFIG_NO_VALUE') == 'now_has_value'
    finally:
        # 清理临时文件
        if os.path.exists(temp_dir):
            shutil.rmtree(temp_dir)