#!/usr/bin/env python3
# Copyright lowRISC contributors.
# Licensed under the Apache License, Version 2.0, see LICENSE for details.
# SPDX-License-Identifier: Apache-2.0

'''A simulator that runs one instruction at a time, reading from a REPL

The input language is simple (and intended to be generated by another program).
Input should appear with one command per line.

The valid commands are as follows. All arguments are shown here as <argname>.
The integer arguments are read with Python's int() function, so should be
prefixed with "0x" if they are hexadecimal.

    start <addr>         Set the PC to <addr> and start OTBN

    step                 Run one instruction. Print trace information to
                         stdout.

    run                  Run instructions until ecall or error. No trace
                         information.

    load_elf <path>      Load the ELF file at <path>, replacing current
                         contents of DMEM and IMEM.

    load_d <path>        Replace the current contents of DMEM with <path>
                         (read as an array of 32-bit little-endian words)

    load_i <path>        Replace the current contents of IMEM with <path>
                         (read as an array of 32-bit little-endian words)

    dump_d <path>        Write the current contents of DMEM to <path> (same
                         format as for load).

    print_regs           Write the contents of all registers to stdout (in hex)

'''

import sys
from typing import List

from sim.decode import decode_file
from sim.elf import load_elf
from sim.sim import OTBNSim


def read_word(arg_name: str, word_data: str) -> int:
    '''Try to read a 32-bit unsigned word'''
    try:
        value = int(word_data, 0)
    except ValueError:
        raise ValueError('Failed to read {!r} as an integer for <{}> argument.'
                         .format(word_data, arg_name)) from None

    if value < 0 or value >> 32:
        raise ValueError('<{}> argument is {!r}: not representable as a u32.'
                         .format(arg_name, word_data))

    return value


def end_command() -> None:
    '''Print a single '.' to stdout and flush, ending the output for command'''
    print('.')
    sys.stdout.flush()


def on_start(sim: OTBNSim, args: List[str]) -> None:
    '''Jump to an address given as the (only) argument and start running'''
    if len(args) != 1:
        raise ValueError('start expects exactly 1 argument. Got {}.'
                         .format(args))

    addr = read_word('addr', args[0])
    if addr & 3:
        raise ValueError('start address must be word-aligned. Got {:#08x}.'
                         .format(addr))

    print('START {:#08x}'.format(addr))
    sim.state.pc = addr
    sim.state.start()


def on_step(sim: OTBNSim, args: List[str]) -> None:
    '''Step one instruction'''
    if len(args):
        raise ValueError('step expects zero arguments. Got {}.'
                         .format(args))

    pc = int(sim.state.pc)

    assert 0 == pc & 3
    insn, changes = sim.step(verbose=False)
    disasm = '(not running)' if insn is None else insn.disassemble(pc)
    print('EXEC {:#08x}:     {}'.format(pc, disasm))
    for trace in changes:
        print('  {}'.format(trace))


def on_run(sim: OTBNSim, args: List[str]) -> None:
    '''Run until ecall or error'''
    if len(args):
        raise ValueError('run expects zero arguments. Got {}.'
                         .format(args))

    num_cycles = sim.run(verbose=False)
    print(' ran for {} cycles'.format(num_cycles))


def on_load_elf(sim: OTBNSim, args: List[str]) -> None:
    '''Load contents of ELF at path given by only argument'''
    if len(args) != 1:
        raise ValueError('load_elf expects exactly 1 argument. Got {}.'
                         .format(args))
    path = args[0]

    print('LOAD_ELF {!r}'.format(path))
    load_elf(sim, path)


def on_load_d(sim: OTBNSim, args: List[str]) -> None:
    '''Load contents of data memory from file at path given by only argument'''
    if len(args) != 1:
        raise ValueError('load_d expects exactly 1 argument. Got {}.'
                         .format(args))
    path = args[0]

    print('LOAD_D {!r}'.format(path))
    with open(path, 'rb') as handle:
        sim.load_data(handle.read())


def on_load_i(sim: OTBNSim, args: List[str]) -> None:
    '''Load contents of insn memory from file at path given by only argument'''
    if len(args) != 1:
        raise ValueError('load_i expects exactly 1 argument. Got {}.'
                         .format(args))
    path = args[0]

    print('LOAD_I {!r}'.format(path))
    sim.load_program(decode_file(path))


def on_dump_d(sim: OTBNSim, args: List[str]) -> None:
    '''Dump contents of data memory to file at path given by only argument'''
    if len(args) != 1:
        raise ValueError('dump_d expects exactly 1 argument. Got {}.'
                         .format(args))
    path = args[0]

    print('DUMP_D {!r}'.format(path))

    with open(path, 'wb') as handle:
        handle.write(sim.state.dmem.dump_le_words())


def on_print_regs(sim: OTBNSim, args: List[str]) -> None:
    '''Print registers to stdout'''
    if len(args):
        raise ValueError('print_regs expects zero arguments. Got {}.'
                         .format(args))

    print('PRINT_REGS')
    for idx, value in enumerate(sim.state.gprs.peek_unsigned_values()):
        print(' x{:<2} = 0x{:08x}'.format(idx, value))
    for idx, value in enumerate(sim.state.wdrs.peek_unsigned_values()):
        print(' w{:<2} = 0x{:064x}'.format(idx, value))


def on_print_call_stack(sim: OTBNSim, args: List[str]) -> None:
    '''Print call stack to stdout first element is the bottom of the stack'''
    if len(args):
        raise ValueError('print_call_stack expects zero arguments. Got {}.'
                         .format(args))

    print('PRINT_CALL_STACK')
    for value in sim.state.gprs.peek_call_stack():
        print('0x{:08x}'.format(value))


_HANDLERS = {
    'start': on_start,
    'step': on_step,
    'run': on_run,
    'load_elf': on_load_elf,
    'load_d': on_load_d,
    'load_i': on_load_i,
    'dump_d': on_dump_d,
    'print_regs': on_print_regs,
    'print_call_stack': on_print_call_stack
}


def on_input(sim: OTBNSim, line: str) -> None:
    '''Process an input command'''
    words = line.split()

    # Just ignore empty lines
    if not words:
        return

    verb = words[0]
    handler = _HANDLERS.get(verb)
    if handler is None:
        raise RuntimeError('Unknown command: {!r}'.format(verb))

    handler(sim, words[1:])
    print('.')
    sys.stdout.flush()


def main() -> int:
    sim = OTBNSim()
    try:
        for line in sys.stdin:
            on_input(sim, line)
    except KeyboardInterrupt:
        print("Received shutdown request, ending OTBN simulation.")
        return 0
    return 0


if __name__ == '__main__':
    sys.exit(main())
