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

'''Runner for NIOS II, based on quartus-flash.py and GDB.'''

from .. import log
from .core import ZephyrBinaryRunner, NetworkPortHelper


class Nios2BinaryRunner(ZephyrBinaryRunner):
    '''Runner front-end for NIOS II.'''

    # From the original shell script:
    #
    #     "XXX [flash] only support[s] cases where the .elf is sent
    #      over the JTAG and the CPU directly boots from __start. CONFIG_XIP
    #      and CONFIG_INCLUDE_RESET_VECTOR must be disabled."

    def __init__(self, cfg, quartus_py=None, cpu_sof=None, tui=False):
        super(Nios2BinaryRunner, self).__init__(cfg)
        self.hex_name = cfg.kernel_hex
        self.elf_name = cfg.kernel_elf
        self.cpu_sof = cpu_sof
        self.quartus_py = quartus_py
        self.gdb_cmd = [cfg.gdb] if cfg.gdb else None
        self.tui_arg = ['-tui'] if tui else []

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

    @classmethod
    def do_add_parser(cls, parser):
        # TODO merge quartus-flash.py script into this file.
        parser.add_argument('--quartus-flash', required=True)
        parser.add_argument('--cpu-sof', required=True,
                            help='path to the the CPU .sof data')
        parser.add_argument('--tui', default=False, action='store_true',
                            help='if given, GDB uses -tui')

    @classmethod
    def create(cls, cfg, args):
        return Nios2BinaryRunner(cfg,
                                 quartus_py=args.quartus_flash,
                                 cpu_sof=args.cpu_sof,
                                 tui=args.tui)

    def do_run(self, command, **kwargs):
        if command == 'flash':
            self.flash(**kwargs)
        else:
            self.debug_debugserver(command, **kwargs)

    def flash(self, **kwargs):
        if self.quartus_py is None:
            raise ValueError('Cannot flash; --quartus-flash not given.')
        if self.cpu_sof is None:
            raise ValueError('Cannot flash; --cpu-sof not given.')

        cmd = [self.quartus_py,
               '--sof', self.cpu_sof,
               '--kernel', self.hex_name]

        self.check_call(cmd)

    def print_gdbserver_message(self, gdb_port):
        log.inf('Nios II GDB server running on port {}'.format(gdb_port))

    def debug_debugserver(self, command, **kwargs):
        # Per comments in the shell script, the NIOSII GDB server
        # doesn't exit gracefully, so it's better to explicitly search
        # for an unused port. The script picks a random value in
        # between 1024 and 49151, but we'll start with the
        # "traditional" 3333 choice.
        gdb_start = 3333
        nh = NetworkPortHelper()
        gdb_port = nh.get_unused_ports([gdb_start])[0]

        server_cmd = (['nios2-gdb-server',
                       '--tcpport', str(gdb_port),
                       '--stop', '--reset-target'])

        if command == 'debugserver':
            self.print_gdbserver_message(gdb_port)
            self.check_call(server_cmd)
        else:
            if self.elf_name is None:
                raise ValueError('Cannot debug; elf is missing')
            if self.gdb_cmd is None:
                raise ValueError('Cannot debug; no gdb specified')

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

            self.print_gdbserver_message(gdb_port)
            self.run_server_and_client(server_cmd, gdb_cmd)
