# -*- coding: utf-8 -*-
# Copyright 2023-2025 NXP
# SPDX-License-Identifier: BSD-3-Clause

from errors import Result, Error, ErrorCode, Ok, exceptcall

# Global parameters used in Python scripts are split in two parts:
#   -  [mandatory parameters] global parameters without default value (GLOBAL_PARAMETERS_WITHOUT_DEFAULT_VALUE)
#   -  [optional parameters] global parameters with default value (GLOBAL_PARAMETERS_WITH_DEFAULT_VALUE)
# Global parameters are set:
#   - automatically by S32 Design Studio when the GUI is used;
#   - manually by user/customer when the GDB CLI is used, the summary of steps are below:
#        * start the GDB with python support and execute commands from a file (eg. gdb-py -x file_commands.txt)
#        * add the following commands in file_commands.txt:
#           + [mandatory parameters] set the global parameters without default value
#               # set debug probe with xxx.yyy.zzz.www IP
#               py _PROBE_IP "s32dbg:xxx.yyy.zzz.www"
#               # set soc name of your board (eg. S32G274A)
#               py _SOC_NAME "S32G274A"
#               # set core name (e.g. M7_0)
#               py _CORE_NAME "M7_0"
#           + [optional parameters] set the global parameters with default value if necessary
#               # enable logging
#               py _IS_LOGGING_ENABLED True
#               # increase the remote timeout when the connection is too slow
#               py _REMOTE_TIMEOUT 180
#               # enable gdb non-stop mode
#               py _NON_STOP_MODE True
#           + source the initialization script specific for your board
#               # initualization script to debug S32G274A
#               source "<S32DS Install Path>/S32DS/tools/S32Debugger/Debugger/scripts/s32g2xx/s32g2xx_generic_bareboard.py"
#           + initialize the board selected. It should only be called for the initial core. In a multicore debugging workflow,
#             the debugger launch for additional cores would omit this step.
#               py board_init()
#           + initialize the core specified
#               py core_init()
#           + load an ELF file
#               load "<your workspace>/s32g274a_rev2_cortex_m7/s32g274a_rev2_cortex_m7_M7_0/Debug_RAM/s32g274a_rev2_cortex_m7_M7_0.elf"
#           + load symbol information for main ELF file
#               symbol-file "<your workspace>/s32g274a_rev2_cortex_m7/s32g274a_rev2_cortex_m7_M7_0/Debug_RAM/s32g274a_rev2_cortex_m7_M7_0.elf"
#
# NOTE: Please look over the documention about how to use Command Line GDB Debugging (GDB CLI) with S32 Debug Probe.

# Global parameters without default value.
GLOBAL_PARAMETERS_WITHOUT_DEFAULT_VALUE = ["_PROBE_IP", "_SOC_NAME", "_CORE_NAME"]

# Global Flash Programmer parameters without default value.
GLOBAL_FP_PARAMETERS_WITHOUT_DEFAULT_VALUE = ["_SOC_NAME", "_FLASH_TYPE", "_FLASH_NAME", "_INIT_SCRIPT", "_PROBE_IP"]


# Global parameters with default value.
GLOBAL_PARAMETERS_WITH_DEFAULT_VALUE = {
    # name:                 default value
    "_JTAG_SPEED": 16000,
    "_GDB_SERVER_PORT": 45000,
    "_RESET_TYPE": "default",
    "_RESET_DELAY": 1,
    "_REMOTE_TIMEOUT": 60,
    "_IS_LOGGING_ENABLED": False,
    "_SECURE_TYPE": None,
    "_SECURE_KEY": None,
    "_LIFECYCLE": None,
    "_CCS_IP": "127.0.0.1",
    "_CCS_PORT": 41475,
    "_DM_RESTRICTED_ADDRESS": 0x0,
    "_NON_STOP_MODE": False
}

# Global Flash Programmers parameters with default value.
GLOBAL_FP_PARAMETERS_WITH_DEFAULT_VALUE = {
    # name:                 default value
    "_JTAG_SPEED": 16000,
    "_GDB_SERVER_PORT": 45000,
    "_RESET_TYPE": "default",
    "_RESET_DELAY": 1,
    "_REMOTE_TIMEOUT": 60,
    "_IS_LOGGING_ENABLED": False,
    "_SECURE_TYPE": None,
    "_SECURE_KEY": None,
    "_LIFECYCLE": None,
    "_CCS_IP": "127.0.0.1",
    "_CCS_PORT": 41475,
    "_RESULTEXCEPTION": True,
    "_CORE_NAME": None
}



# Define a global variable with default value if this is not yet defined.
def iff_undef_gvar(var_name, default_value, glist):
    if var_name not in glist:
        glist[var_name] = default_value


# Check global parameters
@exceptcall(ErrorCode.UndefinedError)
def check_global_parameters(glist):
    err_mesg = ""
    for k, v in GLOBAL_PARAMETERS_WITH_DEFAULT_VALUE.items():
        iff_undef_gvar(k, v, glist)

    for gv in GLOBAL_PARAMETERS_WITHOUT_DEFAULT_VALUE:
        if gv not in glist:
            if err_mesg != "":
                err_mesg += ", "
            err_mesg += gv

    if err_mesg != "":
        return Result(
            Error(
                ErrorCode.UndefinedError,
                "The following global parameters are undefined: {}\n".format(err_mesg),
            )
        )

# Check Flash Programmer global parameters
@exceptcall(ErrorCode.UndefinedError)
def check_fp_global_parameters(glist):
    err_mesg = ""
    for k, v in GLOBAL_FP_PARAMETERS_WITH_DEFAULT_VALUE.items():
        iff_undef_gvar(k, v, glist)

    for gv in GLOBAL_FP_PARAMETERS_WITHOUT_DEFAULT_VALUE:
        if gv not in glist:
            if err_mesg != "":
                err_mesg += ", "
            err_mesg += gv

    if err_mesg != "":
        return Result(
            Error(
                ErrorCode.UndefinedError,
                "The following global parameters are undefined: {}\n".format(err_mesg),
            )
        )
