from __future__ import annotations
from logging import getLogger
from pydantic import Field
import time

from Task.TaskContextBase.task_reset_support_context_base import (
    TaskResetSupportContextBase
)
from Task.TaskContextBase.task_uart_loader_context_base import (
    TaskUartLoaderContextBase, TaskFuncChangeBaudrateContextBase
)
from Task.TaskOperation.reset_operation import (
    ResetOperation, UartLoaderBootSource
)
from Task.TaskOperation.xmodem_operation import (
    XmodemOperation
)
from Task.TaskOperation.uart_loader_operation import (
    UartLoaderOperation
)
from app_context import AppContext

logger = getLogger(__name__)

class TaskEnterXmodemContext(TaskResetSupportContextBase,
                            TaskUartLoaderContextBase,
                            TaskFuncChangeBaudrateContextBase):
    pass


class TaskEnterXmodem:
    """Task class for test diagno throughput via uart loader protocol (Operation-based)"""
    
    def __init__(self, ctx: TaskEnterXmodemContext, app_ctx: AppContext):
        """Initialize TaskDumpBinFile"""
        self.ctx = ctx

        self.reset_operation = ResetOperation(
            ctx.to_reset_operation_init_context(app_ctx)
        )

        self.xmodem_operation = XmodemOperation(
            ctx.to_xmodem_init_context(),
        )

        self.uart_loader_operation = UartLoaderOperation(
            ctx.to_uart_loader_init_context(),
        )

    def run(self):
        """Main execution function for TaskEnterXmodem task"""
        logger.info("=== TaskEnterXmodem Task Started"
                    f" (Mode: {self.ctx.uart_loader_mode.value}) ===")
        is_test_success = False
        try:
            self._run_body()
            logger.info("=== TaskEnterXmodem Task Completed ===")
            is_test_success = True
        finally:
            # Clean up
            try:
                self.uart_loader_operation.close_uart_loader_serial()
            except:
                pass
            try:
                self.reset_operation.module_stop(is_test_success)
            except:
                pass

    def _run_body(self):
        """Core task execution logic without error handling"""
        # Execute mode-specific initialization phase
        self.reset_operation.execute_reset_phase()

        if self.ctx.uart_loader_mode == UartLoaderBootSource.RAM:
            self.xmodem_operation.execute_ram_mode_phase()

        # Common phases for both modes
        self.uart_loader_operation.init_uart_loader_serial()
        self.uart_loader_operation.wait_for_boot_event()
        self.uart_loader_operation.change_baudrate(
            self.ctx.to_change_baudrate_context())
