# -*- coding: utf-8 -*-
"""
    Custom GDB commands for cross-trigger.


 Copyright 2021-2024 NXP

 NXP Confidential and Proprietary. This software is owned or controlled by NXP
 and may only be used strictly in accordance with the applicable license terms.
 By expressly accepting such terms or by downloading, installing, activating
 and/or otherwise using the software, you are agreeing that you have read, and
 that you agree to comply with and are bound by, such license terms. If you do
 not agree to be bound by the applicable license terms, then you may not retain,
 install, activate or otherwise use the software.


"""

import gdb
import os
import sys
import string
import types

CURRENT_DIR = ''.join([os.path.dirname(os.path.realpath(__file__)), '/'])
sys.path.insert(0, CURRENT_DIR)
sys.path.insert(0, CURRENT_DIR + "/../../utils")

import mem_reg_utils as utils
from errors import GtaLibException, ErrorCode

class SetupXTCommand(gdb.Command):
    """Set Cross-Trigger.
usage: xt_set sources [list of cores] destination [list of cores]
 
    [list of cores]  -   lisof cores devided by space.
    """

    def __init__(self):
        """
        Constructor
        """
        super(SetupXTCommand, self).__init__("xt_set", gdb.COMMAND_USER)

    def invoke(self, args, from_tty):
        """ Called when the command is invoked """
        self.dont_repeat()
        argv = gdb.string_to_argv(args)

        if len(argv) < 3:
            raise gdb.GdbError("Error: Invalid number of parameters")
        
        try:
            s = argv.index('sources')
            d = argv.index('destinations')
        except ValueError:
            raise gdb.GdbError("Error: invalid parameter")
        
        ctxs = imports('CORE_CTX')
        if ctxs is None:
            raise gdb.GdbError("Error: Can't find core context")
        
        cmd = "monitor xt set sources "
        for v in argv[s+1:d]:
            cmd += "%s " % ctxs[v]

        cmd += "destinations "
        for v in argv[d+1:]:
            cmd += "%s " % ctxs[v]

        if utils.gdb_exec(cmd, False, True).iserror():
            raise gdb.GdbError("Error: Some cores are not enabled")

        
def variables(module_name):
    module = sys.modules[module_name]
    book = {}
    if module:
        book = {key: value for key, value in module.__dict__.items() if
                not (key.startswith('__') or key.startswith('_'))}
    return book


def imports(param):
    for name in sys.modules:
        if isinstance(sys.modules[name], types.ModuleType):
            book = variables(name)
            if param in book:
                return book[param]

# Custom GDB command for run cores through cross trigger.
class RunXTCommand(gdb.Command):
    """Group launch for cores. After executing this command all debug session related to must be resumed.
Usage: xt_run [list of cores] 
    """

    def __init__(self):
        """
        Constructor
        """
        super(RunXTCommand, self).__init__("xt_run", gdb.COMMAND_USER)

    def invoke(self, args, from_tty):
        """ Called when the command is invoked """
        self.dont_repeat()
        argv = gdb.string_to_argv(args)
        
        ctxs = imports('CORE_CTX')
        if ctxs is None:
            raise gdb.GdbError("Error: Can't find core context")
        
        cmd = "monitor xt run"
        for c in argv:
            cmd += " %s" % ctxs[c]
         
        if utils.gdb_exec(cmd, False, True).iserror():
            raise gdb.GdbError("Error: Some cores are not enabled")


# Custom GDB command for run cores through cross trigger.
class EnableXTCommand(gdb.Command):
    """Enable/Disable cross-trigger settings on the server.
    Usage: xt_enable [true|false] 
    """

    def __init__(self):
        """
        Constructor
        """
        super(EnableXTCommand, self).__init__("xt_enable", gdb.COMMAND_USER)

    def invoke(self, args, from_tty):
        """ Called when the command is invoked """
        self.dont_repeat()
        argv = gdb.string_to_argv(args)
        
        cmd = "monitor xt enable"
        for c in argv:
            cmd += " %s" % c
         
        if utils.gdb_exec(cmd, False, True).iserror():
            raise gdb.GdbError("Error: Some cores are not enabled")
      
        
class RemoveXTCommand(gdb.Command):
    """Remove xt settings from the server. 
    Usage: xt_remove 
    """

    def __init__(self):
        """
        Constructor
        """
        super(RemoveXTCommand, self).__init__("xt_remove", gdb.COMMAND_USER)

    def invoke(self, args, from_tty):
        """ Called when the command is invoked """
        self.dont_repeat()
        argv = gdb.string_to_argv(args)
        
        cmd = "monitor xt remove"
         
        if utils.gdb_exec(cmd, False, True).iserror():
            raise gdb.GdbError("Error: Some cores are not enabled")
      

def create_commands():
    """Create GDB commands."""
    SetupXTCommand()
    RunXTCommand()
    EnableXTCommand()
    RemoveXTCommand()
