# Copyright (c) 2017 Linaro Limited.
# Copyright (c) 2023 Nordic Semiconductor ASA.
#
# SPDX-License-Identifier: Apache-2.0

'''Runner base class for flashing with nrf tools.'''

import abc
from collections import deque
import os
from pathlib import Path
import shlex
import subprocess
import sys
from re import fullmatch, escape

from runners.core import ZephyrBinaryRunner, RunnerCaps

try:
    from intelhex import IntelHex
except ImportError:
    IntelHex = None

ErrNotAvailableBecauseProtection = 24
ErrVerify = 25

UICR_RANGES = {
    'NRF53_FAMILY': {
        'NRFDL_DEVICE_CORE_APPLICATION': (0x00FF8000, 0x00FF8800),
        'NRFDL_DEVICE_CORE_NETWORK': (0x01FF8000, 0x01FF8800),
    },
    'NRF91_FAMILY': {
        'NRFDL_DEVICE_CORE_APPLICATION': (0x00FF8000, 0x00FF8800),
    }
}

class NrfBinaryRunner(ZephyrBinaryRunner):
    '''Runner front-end base class for nrf tools.'''

    def __init__(self, cfg, family, softreset, dev_id, erase=False,
                 reset=True, tool_opt=[], force=False, recover=False):
        super().__init__(cfg)
        self.hex_ = cfg.hex_file
        if family and not family.endswith('_FAMILY'):
            family = f'{family}_FAMILY'
        self.family = family
        self.softreset = softreset
        self.dev_id = dev_id
        self.erase = bool(erase)
        self.reset = bool(reset)
        self.force = force
        self.recover = bool(recover)

        self.tool_opt = []
        for opts in [shlex.split(opt) for opt in tool_opt]:
            self.tool_opt += opts

    @classmethod
    def capabilities(cls):
        return RunnerCaps(commands={'flash'}, dev_id=True, erase=True,
                          reset=True, tool_opt=True)

    @classmethod
    def dev_id_help(cls) -> str:
        return '''Device identifier. Use it to select the J-Link Serial Number
                  of the device connected over USB. '*' matches one or more
                  characters/digits'''

    @classmethod
    def do_add_parser(cls, parser):
        parser.add_argument('--nrf-family',
                            choices=['NRF51', 'NRF52', 'NRF53', 'NRF54L',
                                     'NRF54H', 'NRF91'],
                            help='''MCU family; still accepted for
                            compatibility only''')
        parser.add_argument('--softreset', required=False,
                            action='store_true',
                            help='use reset instead of pinreset')
        parser.add_argument('--snr', required=False, dest='dev_id',
                            help='obsolete synonym for -i/--dev-id')
        parser.add_argument('--force', required=False,
                            action='store_true',
                            help='Flash even if the result cannot be guaranteed.')
        parser.add_argument('--recover', required=False,
                            action='store_true',
                            help='''erase all user available non-volatile
                            memory and disable read back protection before
                            flashing (erases flash for both cores on nRF53)''')

        parser.set_defaults(reset=True)

    def ensure_snr(self):
        if not self.dev_id or "*" in self.dev_id:
            self.dev_id = self.get_board_snr(self.dev_id or "*")
        self.dev_id = self.dev_id.lstrip("0")

    @abc.abstractmethod
    def do_get_boards(self):
        ''' Return an array of Segger SNRs '''

    def get_boards(self):
        snrs = self.do_get_boards()
        if not snrs:
            raise RuntimeError('Unable to find a board; '
                               'is the board connected?')
        return snrs

    @staticmethod
    def verify_snr(snr):
        if snr == '0':
            raise RuntimeError('The Segger SNR obtained is 0; '
                                'is a debugger already connected?')

    def get_board_snr(self, glob):
        # Use nrfjprog or nrfutil to discover connected boards.
        #
        # If there's exactly one board connected, it's safe to assume
        # the user wants that one. Otherwise, bail unless there are
        # multiple boards and we are connected to a terminal, in which
        # case use print() and input() to ask what the user wants.

        re_glob = escape(glob).replace(r"\*", ".+")
        snrs = [snr for snr in self.get_boards() if fullmatch(re_glob, snr)]

        if len(snrs) == 0:
            raise RuntimeError(
                'There are no boards connected{}.'.format(
                        f" matching '{glob}'" if glob != "*" else ""))
        elif len(snrs) == 1:
            board_snr = snrs[0]
            self.verify_snr(board_snr)
            print("Using board {}".format(board_snr))
            return board_snr
        elif not sys.stdin.isatty():
            raise RuntimeError(
                f'refusing to guess which of {len(snrs)} '
                'connected boards to use. (Interactive prompts '
                'disabled since standard input is not a terminal.) '
                'Please specify a serial number on the command line.')

        snrs = sorted(snrs)
        print('There are multiple boards connected{}.'.format(
                        f" matching '{glob}'" if glob != "*" else ""))
        for i, snr in enumerate(snrs, 1):
            print('{}. {}'.format(i, snr))

        p = 'Please select one with desired serial number (1-{}): '.format(
                len(snrs))
        while True:
            try:
                value = input(p)
            except EOFError:
                sys.exit(0)
            try:
                value = int(value)
            except ValueError:
                continue
            if 1 <= value <= len(snrs):
                break

        return snrs[value - 1]

    def ensure_family(self):
        # Ensure self.family is set.

        if self.family is not None:
            return

        if self.build_conf.getboolean('CONFIG_SOC_SERIES_NRF51X'):
            self.family = 'NRF51_FAMILY'
        elif self.build_conf.getboolean('CONFIG_SOC_SERIES_NRF52X'):
            self.family = 'NRF52_FAMILY'
        elif self.build_conf.getboolean('CONFIG_SOC_SERIES_NRF53X'):
            self.family = 'NRF53_FAMILY'
        elif self.build_conf.getboolean('CONFIG_SOC_SERIES_NRF54LX'):
            self.family = 'NRF54L_FAMILY'
        elif self.build_conf.getboolean('CONFIG_SOC_SERIES_NRF54HX'):
            self.family = 'NRF54H_FAMILY'
        elif self.build_conf.getboolean('CONFIG_SOC_SERIES_NRF91X'):
            self.family = 'NRF91_FAMILY'
        else:
            raise RuntimeError(f'unknown nRF; update {__file__}')

    def hex_refers_region(self, region_start, region_end):
        for segment_start, _ in self.hex_contents.segments():
            if region_start <= segment_start <= region_end:
                return True
        return False

    def hex_get_uicrs(self):
        hex_uicrs = {}

        if self.family in UICR_RANGES:
            for uicr_core, uicr_range in UICR_RANGES[self.family].items():
                if self.hex_refers_region(*uicr_range):
                    hex_uicrs[uicr_core] = uicr_range

        return hex_uicrs

    def flush(self, force=False):
        try:
            self.flush_ops(force=force)
        except subprocess.CalledProcessError as cpe:
            if cpe.returncode == ErrNotAvailableBecauseProtection:
                if self.family == 'NRF53_FAMILY':
                    family_help = (
                        '  Note: your target is an nRF53; all flash memory '
                        'for both the network and application cores will be '
                        'erased prior to reflashing.')
                else:
                    family_help = (
                        '  Note: this will recover and erase all flash memory '
                        'prior to reflashing.')
                self.logger.error(
                    'Flashing failed because the target '
                    'must be recovered.\n'
                    '  To fix, run "west flash --recover" instead.\n' +
                    family_help)
            if cpe.returncode == ErrVerify:
                # If there are data in  the UICR region it is likely that the
                # verify failed du to the UICR not been erased before, so giving
                # a warning here will hopefully enhance UX.
                if self.hex_get_uicrs():
                    self.logger.warning(
                        'The hex file contains data placed in the UICR, which '
                        'may require a full erase before reprogramming. Run '
                        'west flash again with --erase, or --recover.')
            raise


    def recover_target(self):
        if self.family == 'NRF53_FAMILY':
            self.logger.info(
                'Recovering and erasing flash memory for both the network '
                'and application cores.')
        else:
            self.logger.info('Recovering and erasing all flash memory.')

        # The network core needs to be recovered first due to the fact that
        # recovering it erases the flash of *both* cores. Since a recover
        # operation unlocks the core and then flashes a small image that keeps
        # the debug access port open, recovering the network core last would
        # result in that small image being deleted from the app core.
        if self.family == 'NRF53_FAMILY':
            self.exec_op('recover', core='NRFDL_DEVICE_CORE_NETWORK')

        self.exec_op('recover')

    def program_hex(self):
        # Get the command use to actually program self.hex_.
        self.logger.info('Flashing file: {}'.format(self.hex_))

        # What type of erase/core arguments should we pass to the tool?
        core = None

        if self.family == 'NRF54H_FAMILY':
            erase_arg = 'ERASE_NONE'

            if self.erase:
                self.exec_op('erase', core='NRFDL_DEVICE_CORE_APPLICATION')
                self.exec_op('erase', core='NRFDL_DEVICE_CORE_NETWORK')

            if self.build_conf.getboolean('CONFIG_SOC_NRF54H20_CPUAPP'):
                if not self.erase:
                    self.exec_op('erase', core='NRFDL_DEVICE_CORE_APPLICATION',
                                 chip_erase_mode='ERASE_UICR',
                                 qspi_erase_mode='ERASE_NONE')
                core = 'NRFDL_DEVICE_CORE_APPLICATION'
            elif self.build_conf.getboolean('CONFIG_SOC_NRF54H20_CPURAD'):
                if not self.erase:
                    self.exec_op('erase', core='NRFDL_DEVICE_CORE_NETWORK',
                                 chip_erase_mode='ERASE_UICR',
                                 qspi_erase_mode='ERASE_NONE')
                core = 'NRFDL_DEVICE_CORE_NETWORK'
        else:
            if self.erase:
                erase_arg = 'ERASE_ALL'
            else:
                if self.family == 'NRF52_FAMILY':
                    erase_arg = 'ERASE_PAGES_INCLUDING_UICR'
                else:
                    erase_arg = 'ERASE_PAGES'

        xip_ranges = {
            'NRF52_FAMILY': (0x12000000, 0x19FFFFFF),
            'NRF53_FAMILY': (0x10000000, 0x1FFFFFFF),
        }
        qspi_erase_opt = None
        if self.family in xip_ranges:
            xip_start, xip_end = xip_ranges[self.family]
            if self.hex_refers_region(xip_start, xip_end):
                qspi_erase_opt = 'ERASE_ALL'

        # What tool commands do we need to flash this target?
        if self.family == 'NRF53_FAMILY':
            # nRF53 requires special treatment due to the extra coprocessor.
            self.program_hex_nrf53(erase_arg, qspi_erase_opt)
        else:
            self.op_program(self.hex_, erase_arg, qspi_erase_opt, defer=True, core=core)

        self.flush(force=False)

    def program_hex_nrf53(self, erase_arg, qspi_erase_opt):
        # program_hex() helper for nRF53.

        # *********************** NOTE *******************************
        # self.hex_ can contain code for both the application core and
        # the network core.
        #
        # We can't assume, for example, that
        # CONFIG_SOC_NRF5340_CPUAPP=y means self.hex_ only contains
        # data for the app core's flash: the user can put arbitrary
        # addresses into one of the files in HEX_FILES_TO_MERGE.
        #
        # Therefore, on this family, we may need to generate two new
        # hex files, one for each core, and flash them individually
        # with the correct '--coprocessor' arguments.
        #
        # Kind of hacky, but it works, and the tools are not capable of
        # flashing to both cores at once. If self.hex_ only affects
        # one core's flash, then we skip the extra work to save time.
        # ************************************************************

        # Address range of the network coprocessor's flash. From nRF5340 OPS.
        # We should get this from DTS instead if multiple values are possible,
        # but this is fine for now.
        net_flash_start = 0x01000000
        net_flash_end   = 0x0103FFFF

        # If there is nothing in the hex file for the network core,
        # only the application core is programmed.
        if not self.hex_refers_region(net_flash_start, net_flash_end):
            self.op_program(self.hex_, erase_arg, qspi_erase_opt, defer=True,
                            core='NRFDL_DEVICE_CORE_APPLICATION')
        # If there is some content that addresses a region beyond the network
        # core flash range, two hex files are generated and the two cores
        # are programmed one by one.
        elif self.hex_contents.minaddr() < net_flash_start or \
             self.hex_contents.maxaddr() > net_flash_end:

            net_hex, app_hex = IntelHex(), IntelHex()
            for start, end in self.hex_contents.segments():
                if net_flash_start <= start <= net_flash_end:
                    net_hex.merge(self.hex_contents[start:end])
                else:
                    app_hex.merge(self.hex_contents[start:end])

            hex_path = Path(self.hex_)
            hex_dir, hex_name = hex_path.parent, hex_path.name

            net_hex_file = os.fspath(
                hex_dir / f'GENERATED_CP_NETWORK_{hex_name}')
            app_hex_file = os.fspath(
                hex_dir / f'GENERATED_CP_APPLICATION_{hex_name}')

            self.logger.info(
                f'{self.hex_} targets both nRF53 coprocessors; '
                f'splitting it into: {net_hex_file} and {app_hex_file}')

            net_hex.write_hex_file(net_hex_file)
            app_hex.write_hex_file(app_hex_file)

            self.op_program(net_hex_file, erase_arg, None, defer=True,
                            core='NRFDL_DEVICE_CORE_NETWORK')
            self.op_program(app_hex_file, erase_arg, qspi_erase_opt, defer=True,
                            core='NRFDL_DEVICE_CORE_APPLICATION')
        # Otherwise, only the network core is programmed.
        else:
            self.op_program(self.hex_, erase_arg, None, defer=True,
                            core='NRFDL_DEVICE_CORE_NETWORK')

    def reset_target(self):
        if self.family == 'NRF52_FAMILY' and not self.softreset:
            self.exec_op('pinreset-enable')

        if self.softreset:
            self.exec_op('reset', option="RESET_SYSTEM")
        else:
            self.exec_op('reset', option="RESET_PIN")

    @abc.abstractmethod
    def do_require(self):
        ''' Ensure the tool is installed '''

    def op_program(self, hex_file, erase, qspi_erase, defer=False, core=None):
        args = {'firmware': {'file': hex_file, 'format': 'NRFDL_FW_INTEL_HEX'},
                'chip_erase_mode': erase, 'verify': 'VERIFY_READ'}
        if qspi_erase:
            args['qspi_erase_mode'] = qspi_erase
        self.exec_op('program', defer, core, **args)

    def exec_op(self, op, defer=False, core=None, **kwargs):
        _op = f'{op}'
        op = {'operation': {'type': _op}}
        if core:
            op['core'] = core
        op['operation'].update(kwargs)
        self.logger.debug(f'defer: {defer} op: {op}')
        if defer or not self.do_exec_op(op, force=False):
            self.ops.append(op)

    @abc.abstractmethod
    def do_exec_op(self, op, force=False):
        ''' Execute an operation. Return True if executed, False if not.
            Throws subprocess.CalledProcessError with the appropriate
            returncode if a failure arises.'''

    def flush_ops(self, force=True):
        ''' Execute any remaining ops in the self.ops array.
            Throws subprocess.CalledProcessError with the appropriate
            returncode if a failure arises.
            Subclasses can override this method for special handling of
            queued ops.'''
        self.logger.debug('Flushing ops')
        while self.ops:
            self.do_exec_op(self.ops.popleft(), force)

    def do_run(self, command, **kwargs):
        self.do_require()

        self.ensure_output('hex')
        if IntelHex is None:
            raise RuntimeError('one or more Python dependencies were missing; '
                               'see the getting started guide for details on '
                               'how to fix')
        self.hex_contents = IntelHex()
        try:
            self.hex_contents.loadfile(self.hex_, format='hex')
        except FileNotFoundError:
            pass

        self.ensure_snr()
        self.ensure_family()

        self.ops = deque()

        if self.recover:
            self.recover_target()
        self.program_hex()
        if self.reset:
            self.reset_target()
        # All done, now flush any outstanding ops
        self.flush(force=True)

        self.logger.info(f'Board with serial number {self.dev_id} '
                         'flashed successfully.')
