# Copyright (c) 2021, Telink Semiconductor
#
# SPDX-License-Identifier: Apache-2.0

import re
import os
import time
import subprocess

from runners.core import ZephyrBinaryRunner, RunnerCaps, BuildConfiguration

class SpiBurnBinaryRunner(ZephyrBinaryRunner):
    '''Runner front-end for SPI_burn.'''

    def __init__(self, cfg, addr, spiburn, iceman, timeout, gdb_port, gdb_ex, erase=False):
        super().__init__(cfg)

        self.spiburn = spiburn
        self.iceman = iceman
        self.addr = addr
        self.timeout = int(timeout)
        self.erase = bool(erase)
        self.gdb_port = gdb_port
        self.gdb_ex = gdb_ex

    @classmethod
    def name(cls):
        return 'spi_burn'

    @classmethod
    def capabilities(cls):
        return RunnerCaps(commands={'flash', 'debug'}, erase=True, flash_addr=True)

    @classmethod
    def do_add_parser(cls, parser):
        parser.add_argument('--addr', default='0x0',
                            help='start flash address to write')
        parser.add_argument('--timeout', default=10,
                            help='ICEman connection establishing timeout in seconds')
        parser.add_argument('--telink-tools-path', help='path to Telink flash tools')
        parser.add_argument('--gdb-port', default='1111', help='Port to connect for gdb-client')
        parser.add_argument('--gdb-ex', default='', nargs='?', help='Additional gdb commands to run')

    @classmethod
    def do_create(cls, cfg, args):

        if args.telink_tools_path:
            spiburn = f'{args.telink_tools_path}/flash/bin/SPI_burn'
            iceman = f'{args.telink_tools_path}/ice/ICEman'
        else:
            # If telink_tools_path arg is not specified then pass to tools shall be specified in PATH
            spiburn = 'SPI_burn'
            iceman  = 'ICEman'

        # Get flash address offset
        if args.dt_flash == 'y':
            build_conf = BuildConfiguration(cfg.build_dir)
            address = hex(cls.get_flash_address(args, build_conf) - build_conf['CONFIG_FLASH_BASE_ADDRESS'])
        else:
            address = args.addr

        return SpiBurnBinaryRunner(cfg, address, spiburn, iceman, args.timeout, args.gdb_port, args.gdb_ex, args.erase)

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

        self.require(self.spiburn)

        # Find path to ICEman with require call
        self.iceman_path = self.require(self.iceman)

        if command == "flash":
            self._flash()

        elif command == "debug":
            self._debug()

        else:
            self.logger.error(f'{command} not supported!')

    def start_iceman(self):

        # Start ICEman as background process
        self.ice_process = self.popen_ignore_int(["./ICEman", '-Z', 'v5', '-l', 'aice_sdp.cfg'],
                                                            cwd=os.path.dirname(self.iceman_path),
                                                            stdout=subprocess.PIPE)

        # Wait till it ready or exit by timeout
        start = time.time()
        while True:
            out = self.ice_process.stdout.readline()
            if b'ICEman is ready to use.' in out:
                break
            if time.time() - start > self.timeout:
                raise RuntimeError("TIMEOUT: ICEman is not ready")

    def stop_iceman(self):
        # Kill ICEman subprocess
        self.ice_process.terminate()

    def _flash(self):

        try:

            # Start ICEman
            self.start_iceman()

            # Compose flash command
            cmd_flash = [self.spiburn, '--addr', str(self.addr), '--image', self.cfg.bin_file]

            if self.erase:
                cmd_flash += ["--erase-all"]

            # Run SPI burn flash tool
            self.check_call(cmd_flash)

        finally:
            self.stop_iceman()

    def _debug(self):

        try:

            # Start ICEman
            self.start_iceman()

            # format -ex commands
            gdb_ex = re.split("(-ex) ", self.gdb_ex)[1::]

            # Compose gdb command
            client_cmd = [self.cfg.gdb, self.cfg.elf_file, '-ex', f'target remote :{self.gdb_port}'] + gdb_ex

            # Run gdb
            self.run_client(client_cmd)

        finally:
            self.stop_iceman()
