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

'''Runner for debugging with JLink.'''

from os import path
import os

from .core import ZephyrBinaryRunner, get_env_or_bail

DEFAULT_JLINK_GDB_PORT = 2331


class JLinkBinaryRunner(ZephyrBinaryRunner):
    '''Runner front-end for the J-Link GDB server.'''

    def __init__(self, device,
                 gdbserver='JLinkGDBServer', iface='swd', elf_name=None,
                 gdb=None, gdb_port=DEFAULT_JLINK_GDB_PORT, tui=None,
                 debug=False):
        super(JLinkBinaryRunner, self).__init__(debug=debug)
        self.device = device
        self.gdbserver_cmd = [gdbserver]
        self.iface = iface
        self.elf_name = elf_name
        self.gdb_cmd = [gdb] if gdb is not None else None
        self.gdb_port = gdb_port
        self.tui_arg = [tui] if tui is not None else []

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

    @classmethod
    def handles_command(cls, command):
        return command in {'debug', 'debugserver'}

    def create_from_env(command, debug):
        '''Create runner from environment.

        Required:

        - JLINK_DEVICE: device name

        Required for 'debug':

        - GDB: gdb to use
        - O: build output directory
        - KERNEL_ELF_NAME: zephyr kernel binary in ELF format

        Optional for 'debug':

        - TUI: if present, passed to gdb server used to flash

        Optional for 'debug', 'debugserver':

        - JLINK_GDBSERVER: default is JLinkGDBServer
        - GDB_PORT: default is 2331
        - JLINK_IF: default is swd
        '''
        device = get_env_or_bail('JLINK_DEVICE')

        gdb = os.environ.get('GDB', None)
        o = os.environ.get('O', None)
        elf = os.environ.get('KERNEL_ELF_NAME', None)
        elf_name = None
        if o is not None:
            if elf is not None:
                elf_name = path.join(o, elf)
        tui = os.environ.get('TUI', None)

        gdbserver = os.environ.get('JLINK_GDBSERVER', 'JLinkGDBServer')
        gdb_port = int(os.environ.get('GDB_PORT',
                                      str(DEFAULT_JLINK_GDB_PORT)))
        iface = os.environ.get('JLINK_IF', 'swd')

        return JLinkBinaryRunner(device, gdbserver=gdbserver,
                                 iface=iface, elf_name=elf_name,
                                 gdb=gdb, gdb_port=gdb_port, tui=tui,
                                 debug=debug)

    def print_gdbserver_message(self):
        print('JLink GDB server running on port {}'.format(self.gdb_port))

    def do_run(self, command, **kwargs):
        server_cmd = (self.gdbserver_cmd +
                      ['-port', str(self.gdb_port),
                       '-if', self.iface,
                       '-device', self.device,
                       '-silent',
                       '-singlerun'])

        if command == 'debugserver':
            self.print_gdbserver_message()
            self.check_call(server_cmd)
        else:
            if self.gdb_cmd is None:
                raise ValueError('Cannot debug; gdb is missing')
            if self.elf_name is None:
                raise ValueError('Cannot debug; elf is missing')
            client_cmd = (self.gdb_cmd +
                          self.tui_arg +
                          [self.elf_name] +
                          ['-ex', 'target remote :{}'.format(self.gdb_port),
                           '-ex', 'monitor halt',
                           '-ex', 'monitor reset',
                           '-ex', 'load'])
            self.print_gdbserver_message()
            self.run_server_and_client(server_cmd, client_cmd)
