import os
import subprocess
import pytest
import sys
sys.path.append('./')
sys.path.append('../')

from bredet.auto_verification.utils.general import merge_and_save_configs

def ensure_log_directory():
    log_dir = 'log'
    os.makedirs(log_dir, exist_ok=True)
    print(f"Ensuring log directory exists: {log_dir}")

def generate_log_file_paths(base_name):
    log_dir = 'log'
    detailed_log_file = os.path.join(log_dir, f"{base_name}_detailed.log")
    return detailed_log_file

def run_command(command, description, detailed_log_file):
    try:
        with open(detailed_log_file, 'a') as log_file:
            log_file.write(f"Running command: {command}\n")
        result = subprocess.run(command, capture_output=True, text=True, shell=True)
        with open(detailed_log_file, 'a') as log_file:
            log_file.write(f"Command output: {result.stdout}\n")
            log_file.write(f"Command error: {result.stderr}\n")

        if result.returncode == 0:
            print(f"Command succeeded: {command}")
        else:
            print(f"Command failed: {command}")
            with open(detailed_log_file, 'a') as log_file:
                log_file.write(f"Test: {description}\n")
                log_file.write(f"Command: {command}\n")
                log_file.write(f"Error Output: {result.stderr}\n")
                log_file.write("-" * 80 + "\n")

        return result.returncode == 0
    except Exception as e:
        with open(detailed_log_file, 'a') as log_file:
            log_file.write(f"{description} failed with exception: {e}\n")
            log_file.write(f"Command: {command}\n")
            log_file.write(f"Exception: {str(e)}\n")
            log_file.write("-" * 80 + "\n")
        print(f"{description} failed with exception: {e}")
        return False

def get_py_files_in_subdirectories(config_path):
    py_files = []
    for subdir in os.listdir(config_path):
        subdir_path = os.path.join(config_path, subdir)
        if os.path.isdir(subdir_path):
            for file in os.listdir(subdir_path):
                if file.endswith('.py') and ('override' not in file):
                    py_files.append(os.path.join(subdir_path, file))
    return py_files

@pytest.fixture(scope="module")
def prepare_test_files():
    ensure_log_directory()

    config_path = "config/test_config"
    override_config = 'bredet/auto_verification/config/auto_config.py'

    py_files_list = get_py_files_in_subdirectories(config_path)
    over_list = []
    for py_file in py_files_list:
        base_name = py_file.rsplit('.', 1)[0]  # 去掉文件扩展名
        extension = py_file.rsplit('.', 1)[1]  # 获取文件扩展名
        over_py_file = f"{base_name}_override.{extension}"
        if not os.path.exists(over_py_file):
            merge_and_save_configs(py_file, override_config, over_py_file, 'test')
        over_list.append(over_py_file)

    return over_list

@pytest.fixture
def detailed_log_file(request):
    py_file = request.node.get_closest_marker('py_file').args[0]
    base_name = os.path.splitext(os.path.basename(py_file))[0]
    return generate_log_file_paths(base_name)

class TestModelPipeline:
    def __init__(self, py_file):
        if py_file is None:
            raise ValueError("py_file must be provided")
        self.py_file = py_file
        base_name = os.path.splitext(os.path.basename(self.py_file))[0]
        self.detailed_log_file = generate_log_file_paths(base_name)

    def setup_method(self):
        # Initialize logging configuration for each test
        with open(self.detailed_log_file, 'a') as log_file:
            log_file.write(f"Starting test with config: {self.py_file}\n")

    def teardown_method(self):
        with open(self.detailed_log_file, 'a') as log_file:
            log_file.write(f"Ending test with config: {self.py_file}\n")

    def test_single_test(self):   # 单卡测试
        command = f"python tools/test.py --config {self.py_file}"
        description = "Single card test"
        result = run_command(command, description, self.detailed_log_file)
        assert result, f"{description} failed"

    def test_multi_devices_test(self):   # 多卡测试
        command = f"torchrun tools/test.py --config {self.py_file}"
        description = "Multi-device test"
        result = run_command(command, description, self.detailed_log_file)
        assert result, f"{description} failed"

def test_pipeline(py_file, detailed_log_file):
    test_model_pipeline = TestModelPipeline(py_file)
    test_model_pipeline.setup_method()
    test_model_pipeline.test_single_test()
    test_model_pipeline.test_multi_devices_test()
    test_model_pipeline.teardown_method()

if __name__ == '__main__':
    pytest.main()报错了  帮我修改一下