#!/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

'''Wrapper script to run the OTBN random instruction generator'''

import argparse
import json
import os
import random
import sys
from typing import Optional, cast

from shared.insn_yaml import InsnsFile, load_insns_yaml

# Ensure that the OTBN utils directory is on sys.path. This means that RIG code
# can import modules like "shared.foo" and get the OTBN shared code.
sys.path.append(os.path.dirname(__file__))

from rig.init_data import init_data_to_json, read_init_data  # noqa: E402
from rig.rig import gen_program, snippets_to_program  # noqa: E402
from rig.snippet import Snippet  # noqa: E402


def get_insns_file() -> Optional[InsnsFile]:
    '''Load up insns.yml'''
    try:
        return load_insns_yaml()
    except RuntimeError as err:
        print(err, file=sys.stderr)
        return None


def gen_main(args: argparse.Namespace) -> int:
    '''Entry point for the gen subcommand'''
    random.seed(args.seed)

    insns_file = get_insns_file()
    if insns_file is None:
        return 1

    # Run the generator
    init_data, snippets = gen_program(args.start_addr, args.size, insns_file)

    # Write out the data and snippets to a JSON file
    ser_data = init_data_to_json(init_data)
    ser_snippets = [snippet.to_json() for snippet in snippets]
    try:
        if args.output == '-':
            json.dump([ser_data, ser_snippets], sys.stdout)
            # Add a newline at end of output: json.dump doesn't, and it makes a
            # bit of a mess of some consoles.
            sys.stdout.write('\n')
        else:
            with open(args.output, 'w') as out_file:
                json.dump(ser_snippets, out_file)
    except OSError as err:
        print('Failed to open json output file {!r}: {}.'
              .format(args.output, err),
              file=sys.stderr)
        return 1

    return 0


def asm_main(args: argparse.Namespace) -> int:
    '''Entry point for the asm subcommand'''

    insns_file = get_insns_file()
    if insns_file is None:
        return 1

    # Load JSON
    try:
        json_data = json.load(args.snippets)
    except json.JSONDecodeError as err:
        print('Snippets file at {!r} is not valid JSON: {}.'
              .format(args.snippets.name, err),
              file=sys.stderr)
        return 1

    # Parse these to proper init data and snippet objects.
    try:
        if not (isinstance(json_data, list) and len(json_data) == 2):
            raise ValueError('Top-level structure should be a length 2 list.')

        json_init_data, json_snippets = json_data
        init_data = read_init_data(json_init_data)
        snippets = [Snippet.from_json(insns_file, idx, x)
                    for idx, x in enumerate(json_snippets)]
    except ValueError as err:
        print('Failed to parse snippets from {!r}: {}'
              .format(args.snippets, err),
              file=sys.stderr)
        return 1

    program = snippets_to_program(snippets)

    # Dump the assembly output, and the linker script too if we're writing to
    # something other than stdout.
    if args.output is None or args.output == '-':
        program.dump_asm(sys.stdout, init_data)
    else:
        try:
            asm_path = args.output + '.s'
            with open(asm_path, 'w') as out_file:
                program.dump_asm(out_file, init_data)
        except OSError as err:
            print('Failed to open asm output file {!r}: {}.'
                  .format(args.output, err),
                  file=sys.stderr)
            return 1

        try:
            ld_path = args.output + '.ld'
            with open(ld_path, 'w') as out_file:
                program.dump_linker_script(out_file, init_data)
        except OSError as err:
            print('Failed to open ld script output file {!r}: {}.'
                  .format(ld_path, err),
                  file=sys.stderr)
            return 1

    return 0


def main() -> int:
    parser = argparse.ArgumentParser()
    subparsers = parser.add_subparsers()

    gen = subparsers.add_parser('gen', help='Generate a random program')
    asm = subparsers.add_parser('asm', help='Convert snippets to assembly')

    gen.add_argument('--output', '-o',
                     default='-',
                     help=("Path for JSON output of generated snippets. The "
                           "special path '-' (which is the default) means to "
                           "write to stdout"))
    gen.add_argument('--seed', type=int, default=0,
                     help='Random seed. Defaults to 0.')
    gen.add_argument('--size', type=int, default=100,
                     help=('Max number of instructions in stream. '
                           'Defaults to 100.'))
    gen.add_argument('--start-addr', type=int, default=0,
                     help='Reset address. Defaults to 0.')
    gen.set_defaults(func=gen_main)

    asm.add_argument('--output', '-o',
                     metavar='out',
                     help=('Base path for output filenames. Will generate '
                           'out.s with an assembly listing and out.ld with '
                           'a linker script. If this is not supplied, the '
                           'assembly (but no linker script) will be dumped '
                           'to stdout.'))
    asm.add_argument('snippets', metavar='path.json',
                     type=argparse.FileType('r'), nargs='?', default=sys.stdin,
                     help=('A JSON file of snippets, as generated by '
                           'otbn-rig gen.'))
    asm.set_defaults(func=asm_main)

    args = parser.parse_args()
    return cast(int, args.func(args))


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