# -*- coding: utf-8 -*-
"""
    RCON initialization script

Copyright 2024 NXP
SPDX-License-Identifier: BSD-3-Clause

"""
import gdb   # @UnresolvedImport  # pylint: disable=F0401
import os
import signal
import time
import os.path
import sys
import importlib
import inspect

from rcon.scripts.utils import gdb_execute
from errors import Result, Ok, Error, ErrorCode, safecall, exceptcall

GTA_INSTALL_DIR = ''.join([os.path.dirname(os.path.realpath(__file__)),
                          '/', '../../../gta/'])
GDB_EXT_DIR = ''.join([os.path.dirname(os.path.realpath(__file__)),
                          '/', '../../../gdb_extensions/'])


#module private instance
_gta_proc = None
_rcon_prompt ='rcon'


def internal_start(args):
    """
        RCON initialization script
    """
    gdb.write('Starting RCON programmer services...\n')
    if internal_initialize_target(args) is False:
        return False

    gdb_execute('set prompt (%s) ' % _rcon_prompt)
    from rcon.gdbcommands.commands import create_commands
     
    rcon_fct_path = args.rconscript
    rcon_fct_script = os.path.basename(rcon_fct_path)
   
    #check if file exists
    if os.path.isfile(rcon_fct_path) is True:
        try:
            fname = os.path.basename(rcon_fct_path)
            path = os.path.dirname(rcon_fct_path)
            sys.path.append(path)
            create_commands(fname)
        except gdb.GdbError as e:
            gdb.write('%s\n' % str(e))
            gdb.write('F-ERROR: S32DS RCON SCRIPTS FAILED\n')
            return False
        gdb.write("Loaded RCON script.\n")
        gdb.write('Available commands: \n')
        gdb.write('  rcon_help\n')
        gdb.write('  rcon_read\n')
        gdb.write('  rcon_write\n\n')
        gdb.write('  Use "command" -h for more information and usage.\n')
    else:
        gdb.write('F-ERROR: can\'t find RCON script %s\n' % rcon_fct_path)
        return False
            

def internal_initialize_target(args):
    """
        Initialize target
    """
    gdb.write('Initializing target...\n')

    #adding set of commands
    rcon_fct_path = args.rconscript
    rcon_fct_script = os.path.basename(rcon_fct_path)
   
    #check if file exists
    if os.path.isfile(rcon_fct_path) is True:
        gdb.write('Running RCON script %s\n' % rcon_fct_path)
        try:
            fname = os.path.basename(rcon_fct_path)
            path = os.path.dirname(rcon_fct_path)
            sys.path.append(path)
            
            DbgInit = importlib.import_module(fname[:-3])

            common_setup_argv = [args.jtag_speed, int(args.gtaip,0), args.reset_type, args.probe, '', args.reset_delay, args.timeout,'', args.log]
            common_setup_argc = len(common_setup_argv)
            
            secure_type = args.secure_type if args.secure_type else None
            secure_key = args.secure_key if args.secure_key else None
            target_lifecycle = args.target_lifecycle if args.target_lifecycle else None

            # ccsip has the following pattern: ip:port
            ccs_vars = args.ccsip.split(':')
            ccs_ip = ccs_vars[0]
            ccs_port = int(ccs_vars[1])
                
            # besides the common setup args, we may also support:
            additional_args = ['',secure_type, secure_key, target_lifecycle, ccs_port, ccs_ip] # elements have to be in this exact order
                
            # use inspect module to get setup args supported by imported module
            supported_setup_argv = inspect.getargspec(DbgInit.RCON_BOARD_INIT)[0]
            supported_setup_argc = len(supported_setup_argv)
                
            # prepare final list of args to be passed
            setup_args = []
            setup_args.extend(common_setup_argv)
            # figure out how many additional parameters does the target setup function support
            # and append them to the parameter list that will be passed
            setup_args.extend(additional_args[:supported_setup_argc - common_setup_argc])
            DbgInit.RCON_BOARD_INIT(*setup_args)
        except gdb.GdbError as e:
            gdb.write('%s\n' % str(e))
            gdb.write('F-ERROR: fail to initialize target\n')
            return False
        gdb.write('Initialized board for RCON %s.\n' % rcon_fct_script)
        
    else:
        gdb.write('F-ERROR: can\'t find RCON script %s\n' % rcon_fct_path)
        return False
    return True

def internal_close_server():
    if _gta_proc is not None:
        gdb.write('Closing debugger server...\n')
        Result(Error(ErrorCode.RCONInitError, 'Could not initialize RCON service')).unwrap()

def start(args):
    """
        Start RCON service
    """
    
    if internal_start(args) is False:
        internal_close_server()
        return False
    return True

