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

'''ARC architecture-specific runner.'''

from os import path
import os
import shlex

from .core import ZephyrBinaryRunner, get_env_or_bail

DEFAULT_ARC_TCL_PORT = 6333
DEFAULT_ARC_TELNET_PORT = 4444
DEFAULT_ARC_GDB_PORT = 3333


class ArcBinaryRunner(ZephyrBinaryRunner):
    '''Runner front-end for the ARC architecture, using openocd.'''

    # This unusual 'flash' implementation matches the original shell script.
    #
    # It works by starting a GDB server in a separate session, connecting a
    # client to it to load the program, and running 'continue' within the
    # client to execute the application.
    #
    # TODO: exit immediately when flashing is done, leaving Zephyr running.

    def __init__(self, elf, zephyr_base, arch, board_name, python,
                 gdb, openocd='openocd', extra_init=None, default_path=None,
                 tui=None, tcl_port=DEFAULT_ARC_TCL_PORT,
                 telnet_port=DEFAULT_ARC_TELNET_PORT,
                 gdb_port=DEFAULT_ARC_GDB_PORT, debug=False):
        super(ArcBinaryRunner, self).__init__(debug=debug)
        self.elf = elf
        self.zephyr_base = zephyr_base
        self.arch = arch
        self.board_name = board_name
        self.python = python
        self.gdb = gdb
        search_args = []
        if default_path is not None:
            search_args = ['-s', default_path]
        self.openocd_cmd = [openocd] + search_args
        self.extra_init = extra_init if extra_init is not None else []
        self.tui = tui
        self.tcl_port = tcl_port
        self.telnet_port = telnet_port
        self.gdb_port = gdb_port

    def replaces_shell_script(shell_script, command):
        return (command in {'flash', 'debug', 'debugserver'} and
                shell_script == 'arc_debugger.sh')

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

        Required:

        - O: build output directory
        - KERNEL_ELF_NAME: zephyr kernel binary in ELF format
        - ZEPHYR_BASE: zephyr Git repository base directory
        - ARCH: board architecture
        - BOARD_NAME: zephyr name of board
        - PYTHON: python executable
        - GDB: gdb executable

        Optional:

        - OPENOCD: path to openocd, defaults to openocd
        - OPENOCD_EXTRA_INIT: initialization command for GDB server
        - OPENOCD_DEFAULT_PATH: openocd search path to use
        - TUI: if present, passed to gdb server used to flash
        - TCL_PORT: openocd TCL port, defaults to 6333
        - TELNET_PORT: openocd telnet port, defaults to 4444
        - GDB_PORT: openocd gdb port, defaults to 3333
        '''
        elf = path.join(get_env_or_bail('O'),
                        get_env_or_bail('KERNEL_ELF_NAME'))
        zephyr_base = get_env_or_bail('ZEPHYR_BASE')
        arch = get_env_or_bail('ARCH')
        board_name = get_env_or_bail('BOARD_NAME')
        python = get_env_or_bail('PYTHON')
        gdb = get_env_or_bail('GDB')

        openocd = os.environ.get('OPENOCD', 'openocd')
        extra_init = os.environ.get('OPENOCD_EXTRA_INIT', None)
        if extra_init is not None:
            extra_init = shlex.split(extra_init)
        default_path = os.environ.get('OPENOCD_DEFAULT_PATH', None)
        tui = os.environ.get('TUI', None)
        tcl_port = int(os.environ.get('TCL_PORT',
                                      str(DEFAULT_ARC_TCL_PORT)))
        telnet_port = int(os.environ.get('TELNET_PORT',
                                         str(DEFAULT_ARC_TELNET_PORT)))
        gdb_port = int(os.environ.get('GDB_PORT',
                                      str(DEFAULT_ARC_GDB_PORT)))

        return ArcBinaryRunner(elf, zephyr_base, arch, board_name, python,
                               gdb, openocd=openocd, extra_init=extra_init,
                               default_path=default_path, tui=tui,
                               tcl_port=tcl_port, telnet_port=telnet_port,
                               gdb_port=gdb_port, debug=debug)

    def run(self, command, **kwargs):
        if command not in {'flash', 'debug', 'debugserver'}:
            raise ValueError('{} is not supported'.format(command))

        kwargs['openocd-cfg'] = path.join(self.zephyr_base, 'boards',
                                          self.arch, self.board_name,
                                          'support', 'openocd.cfg')

        if command in {'flash', 'debug'}:
            self.flash_debug(command, **kwargs)
        else:
            self.debugserver(**kwargs)

    def flash_debug(self, command, **kwargs):
        config = kwargs['openocd-cfg']

        server_cmd = (self.openocd_cmd +
                      ['-f', config] +
                      self.extra_init +
                      ['-c', 'tcl_port {}'.format(self.tcl_port),
                       '-c', 'telnet_port {}'.format(self.telnet_port),
                       '-c', 'gdb_port {}'.format(self.gdb_port),
                       '-c', 'init',
                       '-c', 'targets',
                       '-c', 'halt'])

        tui_arg = []
        if self.tui is not None:
            tui_arg = [self.tui]

        continue_arg = []
        if command == 'flash':
            continue_arg = ['-ex', 'c']

        gdb_cmd = ([self.gdb] +
                   tui_arg +
                   ['-ex', 'target remote :{}'.format(self.gdb_port),
                    '-ex', 'load'] +
                   continue_arg +
                   [self.elf])

        self.run_server_and_client(server_cmd, gdb_cmd)

    def debugserver(self, **kwargs):
        config = kwargs['openocd-cfg']
        cmd = (self.openocd_cmd +
               ['-f', config,
                '-c', 'init',
                '-c', 'targets',
                '-c', 'reset halt'])
        self.check_call(cmd)
