#!/usr/bin/env python
"""
@file jlinkob_reset_support.py

@brief J-Link OB reset support implementation using OpenOCD

Copyright (C) Atmosic 2025
"""
from __future__ import annotations
from logging import getLogger

from reset_support.reset_support_base import ResetSupportBase
from lib.openocd_wrapper import OpenocdWrapper
from error.atmosic_error import ResetSupportError
from error.inner_errorcodes import ResetSupportErrorCode

logger = getLogger(__name__)

class JlinkobResetSupport(ResetSupportBase):
    """J-Link OB reset support using OpenOCD wrapper"""
    
    def __init__(self, jlink_sn):
        """Initialize J-Link OB reset support"""
        self.jlink_sn = jlink_sn
        self.ocd = OpenocdWrapper(jlink_sn)
        
    def reset_normal_boot(self, timeout_ms: int = 5000) -> None:
        """Reset device to normal boot mode using OpenOCD

        Args:
            timeout_ms: Timeout in milliseconds for reset operation
        """
        logger.info("[JlinkobReset] Attempting to reset device to normal mode...")

        # Use OpenOCD to reset device to normal boot mode
        result = self.ocd.cmd("reset_normal_boot").options(
            timeout_ms=timeout_ms
        ).run_then_kill()

        logger.info(f"[JlinkobReset] OpenOCD reset result: {result}")

        # Check if reset was successful
        # For run_then_kill() mode, OpenOCD is killed after reaching ready state,
        # so we check for "waiting to be killed" in output rather than returncode
        output = result.get("output", "")
        success = "waiting to be killed" in output.lower()

        if not success:
            raise ResetSupportError(
                "Normal boot reset failed - no 'waiting to be killed'"
                " found in output",
                ResetSupportErrorCode.NORMAL_BOOT_FAILED
            )

        logger.info("[JlinkobReset] Normal boot reset successful")

    def reset_bboot_mode(self, timeout_ms: int = 5000) -> None:
        """Reset device to bboot mode using OpenOCD

        Args:
            timeout_ms: Timeout in milliseconds for reset operation
        """
        logger.info("[JlinkobReset] Attempting to reset device to bboot mode...")

        # Use OpenOCD to reset device to bboot mode
        result = self.ocd.cmd("reset_with_still_bboot").options(
            timeout_ms=timeout_ms
        ).run_then_kill()

        logger.debug(f"[JlinkobReset] OpenOCD bboot reset result: {result}")

        # Check if reset was successful
        # For run_then_kill() mode, OpenOCD is killed after reaching ready state,
        # so we check for "waiting to be killed" in output rather than returncode
        output = result.get("output", "")
        success = "waiting to be killed" in output.lower()

        if not success:
            raise ResetSupportError(
                "Bboot reset failed - no 'waiting to be killed' found in"
                " output",
                ResetSupportErrorCode.BBOOT_RESET_FAILED
            )
        logger.info("[JlinkobReset] Bboot reset successful")
    
    def get_name(self) -> str:
        """Get the name of this reset support implementation
        
        Returns:
            Human-readable name
        """
        return "J-Link OB Reset Support (OpenOCD)"
