#!/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.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
    snippets, program = gen_program(args.start_addr, args.size, insns_file)

    # Write out the snippets to a JSON file
    ser_snippets = [snippet.to_json() for snippet in snippets]
    try:
        if args.output == '-':
            json.dump(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 snippets JSON
    try:
        snippets_json = 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 snippet objects and then make a program by
    # combining them
    try:
        if not isinstance(snippets_json, list):
            raise ValueError('Top-level structure should be a list.')
        snippets = [Snippet.from_json(insns_file, idx, x)
                    for idx, x in enumerate(snippets_json)]
    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.
    if args.output is None or args.output == '-':
        program.dump_asm(sys.stdout)
    else:
        try:
            asm_path = args.output + '.S'
            with open(asm_path, 'w') as out_file:
                program.dump_asm(out_file)
        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)
        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())
