# radar_data_reader/core/cpp_runner.py

"""
Core runner for executing the external C++ g_reconvert.exe application.
Handles subprocess creation, output streaming to a queue, and error management.
"""

import subprocess
import os
import re
import multiprocessing as mp
from ..utils import logger

log = logger.get_logger(__name__)

# Espressione regolare per identificare l'inizio dell'analisi di un nuovo file
FILE_PROGRESS_REGEX = re.compile(r"g_reconvert-I\[_.*?\.rec\]: \[(\d+)\]")


def run_cpp_converter(
    command_list: list[str],
    result_queue: mp.Queue,
    output_directory: str,
    is_part_of_analysis: bool = False,
):
    """
    Executes the g_reconvert command and streams its output to a queue.
    """
    process = None
    try:
        exe_path = command_list[0]
        if not os.path.exists(exe_path):
            error_msg = f"Executable not found or invalid path: '{exe_path}'"
            log.error(error_msg)
            if not is_part_of_analysis:
                result_queue.put({"type": "error", "message": error_msg})
            return

        working_directory = output_directory
        if not os.path.exists(working_directory):
            try:
                os.makedirs(working_directory)
                log.info(f"Created output directory: {working_directory}")
            except OSError as e:
                error_msg = (
                    f"Failed to create output directory {working_directory}: {e}"
                )
                log.error(error_msg)
                if not is_part_of_analysis:
                    result_queue.put({"type": "error", "message": error_msg})
                return

        creationflags = subprocess.CREATE_NO_WINDOW if os.name == "nt" else 0

        process = subprocess.Popen(
            command_list,
            stdout=subprocess.PIPE,
            stderr=subprocess.STDOUT,
            text=True,
            encoding="utf-8",
            errors="replace",
            bufsize=1,
            creationflags=creationflags,
            cwd=working_directory,
        )

        log.info(
            f"Started C++ converter process (PID: {process.pid}) in directory: {working_directory}."
        )

        if process.stdout:
            for line in iter(process.stdout.readline, ""):
                progress_match = FILE_PROGRESS_REGEX.search(line)
                if progress_match:
                    file_number = int(progress_match.group(1))
                    result_queue.put(
                        {"type": "file_progress", "file_number": file_number}
                    )

                line_lower = line.lower().strip()
                if "g_reconvert-w" in line_lower or "changed: a-err" in line_lower:
                    continue

                msg_type = "INFO"
                if (
                    "error" in line_lower
                    or "fail" in line_lower
                    or "exception" in line_lower
                ):
                    msg_type = "ERROR"
                elif "warn" in line_lower:
                    msg_type = "WARNING"
                elif "success" in line_lower or "finish" in line_lower:
                    msg_type = "SUCCESS"

                result_queue.put(
                    {"type": "log", "level": msg_type, "message": line.strip()}
                )

        return_code = process.wait()
        log.info(f"C++ converter process finished with return code: {return_code}")

        if not is_part_of_analysis:
            if return_code != 0:
                result_queue.put(
                    {
                        "type": "error",
                        "message": f"Conversion process failed with return code {return_code}.",
                    }
                )
            else:
                result_queue.put(
                    {
                        "type": "success",
                        "message": "Conversion process completed successfully.",
                    }
                )

    except FileNotFoundError:
        error_msg = (
            f"Command not found: '{command_list[0]}'. Please check the executable path."
        )
        log.error(error_msg)
        if not is_part_of_analysis:
            result_queue.put({"type": "error", "message": error_msg})
    except PermissionError:
        error_msg = (
            f"Permission denied to execute '{command_list[0]}'. Check file permissions."
        )
        log.error(error_msg)
        if not is_part_of_analysis:
            result_queue.put({"type": "error", "message": error_msg})
    except Exception as e:
        error_msg = f"An unexpected error occurred during C++ converter execution: {e}"
        log.error(error_msg, exc_info=True)
        if not is_part_of_analysis:
            result_queue.put({"type": "error", "message": error_msg})
