"""
Plugin Reset Support Implementation

This module provides reset support using plugin Python script
for device reset operations.
"""
from __future__ import annotations

from serial import Serial
from time import sleep
from logging import getLogger
import sys
import runpy
from pathlib import Path

from .reset_support_base import ResetSupportBase
from error.atmosic_error import ResetSupportError
from error.inner_errorcodes import ResetSupportErrorCode

logger = getLogger(__name__)

class PluginResetSupport(ResetSupportBase):
    """Reset support implementation using RTS signal"""
    
    def __init__(self, plugin_start_py: str, plugin_end_py: str,
                 test_times: int, max_test_times: int):
        """Initialize Plugin reset support"""
        logger.info("PluginResetSupport initialized")
        self.plugin_start_py = plugin_start_py
        self.plugin_end_py = plugin_end_py
        self.origin_args = sys.argv.copy()
        self.test_times = test_times
        self.max_test_times = max_test_times
        self.is_started = False

    def _execute_plugin(self, plugin_path: str, is_success: bool = False
                        ) -> None:
        """Execute a plugin Python script using runpy

        This method loads and executes a Python script as a module,
        including code in the 'if __name__ == "__main__":' block.

        Args:
            plugin_path: Path to the Python script to execute

        Raises:
            ResetSupportError: If plugin execution fails
        """
        if not plugin_path:
            logger.warning("Plugin path is empty, skipping execution")
            return

        plugin_file = Path(plugin_path)
        if not plugin_file.exists():
            error_msg = f"Plugin file not found: {plugin_path}"
            logger.error(error_msg)
            raise ResetSupportError(
                error_msg, ResetSupportErrorCode.PLUGIN_START_FILE_NOT_FOUND)

        logger.info(
            f"Executing plugin: {plugin_path}\n\n"
            "#################### Start of plugin output ####################")

        # Save original sys.argv and restore it after execution
        original_argv = sys.argv.copy()

        try:
            # Set sys.argv to include the plugin path and original arguments
            # This makes the plugin think it was called directly from command line
            sys.argv = [str(plugin_file.absolute())] + self.origin_args[1:]
            sys.argv += ["--test-times", f"{self.test_times}"]
            sys.argv += ["--max-test-times", f"{self.max_test_times}"]
            if is_success:
                sys.argv += ["--is-finish-test"]

            # Execute the plugin script as __main__ module
            # This will run code in 'if __name__ == "__main__":' block
            runpy.run_path(str(plugin_file.absolute()), run_name="__main__")

            logger.info(
                f"Plugin executed successfully: {plugin_path}\n"
                "#################### End of plugin output ####################"
                "\n")
            self.is_started = True

        except Exception as e:
            error_msg = f"Plugin execution failed: {plugin_path}, error: {e}"
            logger.error(error_msg)
            logger.error(f"Exception type: {type(e).__name__}")
            logger.error(f"Exception details: {str(e)}")
            raise ResetSupportError(
                error_msg, ResetSupportErrorCode.PLUGIN_EXECUTION_FAILED)
        finally:
            # Always restore original sys.argv
            sys.argv = original_argv
    
    def reset_bboot_mode(self, timeout_ms: int = 3000) -> None:
        """Reset device to bboot mode using plugin script

        Args:
            timeout_ms: Timeout in milliseconds
        """
        logger.info("PluginResetSupport: Starting reset")
        self._execute_plugin(self.plugin_start_py)
        logger.info("PluginResetSupport: starting reset completed")

    def reset_normal_boot(self, timeout_ms: int = 5000) -> None:
        """Reset device to normal boot mode using plugin script

        Args:
            timeout_ms: Timeout in milliseconds
        """
        logger.error("RtsResetSupport: reset_normal_boot - Not implemented yet")
        raise ResetSupportError("RTS normal boot reset not implemented yet",
                                ResetSupportErrorCode.NOT_IMPLEMENTED)

    def module_stop(self, is_test_success: bool):
        """Stop the module and cleanup resources"""
        logger.info("PluginResetSupport: Ending reset")
        self._execute_plugin(self.plugin_end_py, is_test_success)
        self.is_started = False
        logger.info("PluginResetSupport: Ending reset completed")

    def __del__(self):
        logger.info("PluginResetSupport deleted")
        if self.is_started:
            self.module_stop(False)