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 MakefileParser

def test_makefile_parser_read():
    """测试 MakefileParser 类的读取功能"""
    parser = MakefileParser(os.path.join(os.path.dirname(__file__),  "data", "test.mk"))
    with open(os.path.join(os.path.dirname(__file__), '.tmp', 'test_parsed.json'), 'w') as f:
        f.write(f"{parser}")
    # 测试获取简单变量
    assert parser.get('SIMPLE_VAR') == ['simple', 'value']
    
    # 测试获取使用不同分隔符的变量
    assert parser.get('COLON_VAR') == ['immediately', 'expanded', 'value']
    
    # 测试获取多行变量
    multiline = parser.get('MULTILINE_VAR')
    assert len(multiline) == 6
    # 测试带注释的变量
    assert parser.get('WITH_COMMENT')[0].startswith('value')
    
    # 测试不存在的变量返回默认值
    assert parser.get('NON_EXISTENT', 'default') == 'default'
    
    # 测试复合变量
    assert parser.get('COMPOUND_VAR') == ['$(SIMPLE_VAR)', 'and', '$(COLON_VAR)']
    
    # 测试空变量
    assert parser.get('EMPTY_VAR') == []

def test_makefile_parser_rw():
    """测试 MakefileParser 类的读写功能，看是否能够正确写回文件"""
    src_file = os.path.join(os.path.dirname(__file__),  "data", "test.mk")
    parser = MakefileParser(src_file)
    # new_file = os.path.join(os.path.dirname(__file__), 'test_rw.mk')
    temp_dir = tempfile.mkdtemp()
    new_file = os.path.join(temp_dir, 'test_copy.mk')
    shutil.copy(os.path.join(os.path.dirname(__file__),  "data", "test.mk"), new_file)

    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_makefile_parser_modify():
    """测试 MakefileParser 类的修改功能"""
    # 创建测试文件的副本
    temp_dir = tempfile.mkdtemp()
    temp_file = os.path.join(temp_dir, 'test_copy.mk')
    shutil.copy(os.path.join(os.path.dirname(__file__),  "data", "test.mk"), temp_file)
    
    try:
        parser = MakefileParser(temp_file)

        # 修改现有变量
        parser['SIMPLE_VAR'] = 'modified value'
        
        # 添加新变量
        parser['NEW_VAR'] = 'new value'
        
        #在SIMPLE_VAR前面插入新变量
        # idx = parser.index('SIMPLE_VAR')
        parser.insert('SIMPLE_VAR', 'NEW_VAR1', ':=', 'new value', '# comment')

        # 添加多行变量
        parser['NEW_MULTILINE'] = ['line 1', 'line 2', 'line 3']
        
        # 删除变量
        del parser['EMPTY_VAR']
        
        # 使用正则
        parser['REGEX_VAR'] = 'new value'
        parser['REGEX_.* := new value'] = 'REGEX_VAR := regex value'

        
        # 刷新到文件
        parser.flush()
        with open(os.path.join(os.path.dirname(__file__), '.tmp', 'test_parsed.json'), 'w') as f:
            f.write(f"{parser}")
        # 重新加载解析器验证修改
        new_parser = MakefileParser(temp_file)
        assert new_parser.get('SIMPLE_VAR') == ['modified', 'value']
        assert new_parser.get('NEW_VAR') == ['new', 'value']
        assert new_parser.get('NEW_VAR1') == ['new', 'value']
        assert len(new_parser.get('NEW_MULTILINE')) == 6
        assert new_parser.get('EMPTY_VAR') is None
        assert new_parser.get('REGEX_VAR') == ['regex', 'value']
        del new_parser['REGEX_VAR']
        assert new_parser.get('REGEX_VAR') is None
    finally:
        # 清理临时文件
        if os.path.exists(temp_dir):
            shutil.rmtree(temp_dir)

def test_makefile_parser_content_preservation():
    """测试 MakefileParser 类是否保留原始文件的注释和结构"""
    # 创建测试文件的副本
    temp_dir = tempfile.mkdtemp()
    temp_file = os.path.join(temp_dir, 'test_copy.mk')
    shutil.copy(os.path.join(os.path.dirname(__file__),  "data", "test.mk"), 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 = MakefileParser(temp_file)
        parser['SIMPLE_VAR'] = 'modified but preserving structure'
        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 original_line_count == modified_line_count
        
        # 注释应该完全保留
        assert original_comment_count == modified_comment_count
        
    finally:
        # 清理临时文件
        if os.path.exists(temp_dir):
            shutil.rmtree(temp_dir)