# -*- coding: utf-8 -*-
"""
    Implementation of Flash Programmer service

Copyright 2015 Freescale Semiconductor, Inc.
Copyright 2017-2020, 2023-2025 NXP.
SPDX-License-Identifier: BSD-3-Clause

"""

import gdb  # @UnresolvedImport  # pylint: disable=F0401
import argparse
import shlex
from flash.gdbcommands import cmd_name
from errors import Ok, Result, Error, ErrorCode

###################################################################
######### Start flash programmer services command
###################################################################
class CwFpServices(gdb.Command):
    """
        Start CodeWarrior flash programmer services.
    """

    #make sure that invoke gets called only once
    instance = None

    def __init__(self):
        super(CwFpServices, self).__init__(cmd_name.CMD_CW_FP_SERVICES,
        gdb.COMMAND_USER)
        parser = argparse.ArgumentParser(description='DS for Vision \
            Flash Programming services.', fromfile_prefix_chars='|>@')
        group = parser.add_argument_group('Target Configuration')
        group.add_argument('-d', '--dev',
                            metavar = '',
                            help = 'select flash memory type')
        group.add_argument('-r', '--reset_timeout',
                            metavar = '',
                            type = int,
                            default = 1,
                            help = 'reset timeout')
        group.add_argument('-c', '--core',
                            metavar = '',
                            help = 'select working core')
        parser.add_argument('--probe',
                            metavar = '',
                            help = 'specify connection probe used to connect to \
                            target or implicitly use usb if no option is provided')
        parser.add_argument('--ccsip',
                            metavar = '',
                            default = '',
                            help = 'specify ccs connection address and \
                            port like 127.0.0.1:41475')
        parser.add_argument('--gtaip',
                            metavar = '',
                            default = '',
                            help = 'specify debugger port')
        parser.add_argument('-t', '--timeout', 
                            metavar = '',
                            type = int,
                            default = 100,
                            help = 'specify operations timeout - useful in case \
                            of writing a big kernel image')
        parser.add_argument('--jtag_speed',
                            metavar = '',
                            type = int,
                            default = 16000,
                            help = 'specify jtag speed')
        parser.add_argument('--no_init',
                            action="store_true",
                            help = 'don\'t initialize target it is already \
                            initialized')
        parser.add_argument('-i', '--interactive',
                            action="store_true",
                            help = 'enter interactive mode where user can \
                            configure target connection')
        parser.add_argument('--reset_delay', 
                            metavar = '',
                            type = int,
                            default = 1,
                            help = 'specify reset delay')
        parser.add_argument('--reset_type', 
                            metavar = '',
                            default = 'default',
                            help = 'specify reset type')
        parser.add_argument('--init', 
                            metavar = '',
                            default = '',
                            help = 'specify board initialization script')
        parser.add_argument('--flash_name', 
                            metavar = '',
                            default = '',
                            help = 'specify board flash name')
        parser.add_argument('--log', 
                            metavar = '',
                            type = self.str2bool,
                            default = False,
                            help = 'enable log')
        parser.add_argument('--soc_name', 
                            metavar = '',
                            default = '',
                            help = 'SoC name')
        parser.add_argument('--secure_type', 
                            metavar = '',
                            default = '',
                            help = 'secure_type')
        parser.add_argument('--secure_key', 
                            metavar = '',
                            default = '',
                            help = 'secure_key')
        parser.add_argument('--target_lifecycle',
                            metavar = '',
                            default = '',
                            help = 'specify target lifecycle')
        parser.add_argument('--core_name',
                            metavar = '',
                            default = '',
                            help = 'core name')
        self._parser = parser

    def invoke(self, argument, from_tty):
        self.dont_repeat()
        ret = False
        try:
            ret = self.start_service(argument)
        except SystemExit:
            pass
        return ret

    def dont_repeat(self):
        gdb.Command.dont_repeat(self)
        
    def str2bool(self, v):
        if v.lower() in ('yes', 'true', 't', 'y', '1'):
            return True
        elif v.lower() in ('no', 'false', 'f', 'n', '0'):
            return False
        else:
            Result(Error(ErrorCode.ValueError, 'F-ERROR: Boolean value expected.')).unwrap()

    def start_service(self, argument):
        args = self._parser.parse_args(shlex.split(argument))
        ret = False
        if CwFpServices.instance is None:
            from flash.scripts.flash_init import start
            ret = start(args)
            if ret is True:
                CwFpServices.instance = self
            else:
                Result(Error(ErrorCode.FlashInitError, 'Could not initialize Flash service')).unwrap()
        else:
            gdb.write('Service already started\n')
        return ret

    def complete(self, text, word):
        params = 'dev soc board conn ccsip gtaip timeout jtag_speed \
            no_reset no_init help interactive'
        matching_params = [param for param in params.split() if param.startswith(word)]
        return matching_params

###################################################################
######### Register CodeWarrior Flash Programmer services ##########
###################################################################
def load_fp_services():
    """
        Add flash programmer services
    """
    CwFpServices()

def start_fp_services(argument):
    """
        Add flash programmer services
    """

    instance = CwFpServices()
    return instance.invoke(argument, False)
    
def reset_board(init_script):
    """
        Functional reset wrapper
    """
    if CwFpServices.instance is not None:
        from flash.scripts.flash_init import reset_board
        ret = reset_board(init_script)
        if ret is True:
            gdb.write("Reseting board done...\n")
        else:
            gdb.write("Reseting board failed...\n")



