#!/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 wrapper around riscv32-unknown-elf-ld for OTBN

This just adds the OTBN linker script and calls the underlying
linker.'''

from contextlib import contextmanager
import os
import subprocess
import sys
import tempfile
from typing import Iterator, List, Optional

from mako.template import Template  # type: ignore
from mako import exceptions  # type: ignore

from shared.mem_layout import get_memory_layout
from shared.toolchain import find_tool


def interpolate_linker_script(in_path: str, out_path: str) -> None:
    mems = get_memory_layout()

    try:
        template = Template(filename=in_path)
        rendered = template.render(imem_lma = mems['IMEM'][0],
                                   imem_length = mems['IMEM'][1],
                                   dmem_lma = mems['DMEM'][0],
                                   dmem_length = mems['DMEM'][1])
    except OSError as err:
        raise RuntimeError(str(err)) from None
    except:  # noqa: 722
        raise RuntimeError(exceptions.text_error_template().render()) from None

    try:
        with open(out_path, 'w') as out_file:
            out_file.write(rendered)
    except FileNotFoundError:
        raise RuntimeError('Failed to open output file at {!r}.'
                           .format(out_path)) from None


@contextmanager
def mk_linker_script() -> Iterator[str]:
    ld_in = os.path.abspath(os.path.join(os.path.dirname(__file__),
                                         '..', 'data', 'otbn.ld.tpl'))
    with tempfile.TemporaryDirectory(prefix='otbn-ld-') as tmpdir:
        ld_out = os.path.join(tmpdir, 'otbn.ld')
        try:
            interpolate_linker_script(ld_in, ld_out)
        except RuntimeError as err:
            sys.stderr.write('Failed to interpolate linker script: {}\n'
                             .format(err))
            return 1

        yield ld_out


def run_ld(ld_script: Optional[str], args: List[str]) -> int:
    '''Run the underlying linker and return the status code'''
    ld_name = find_tool('ld')
    cmd = [ld_name]
    if ld_script is not None:
        cmd.append('--script={}'.format(ld_script))
    cmd += args

    try:
        return subprocess.run(cmd).returncode
    except FileNotFoundError:
        sys.stderr.write('Unknown command: {!r}. '
                         '(is it installed and on your PATH?)\n'
                         .format(ld_name))
        return 127


def main() -> int:
    # Only add the --script argument if the caller isn't supplying one
    # themselves. This argument accumulates (so -T foo -T bar is like
    # concatenating foo and bar), so we mustn't supply our own if the user
    # has one.
    needs_script = True
    for arg in sys.argv[1:]:
        if arg == '-T' or arg.startswith('--script='):
            needs_script = False
            break

    if needs_script:
        with mk_linker_script() as script_path:
            return run_ld(script_path, sys.argv[1:])
    else:
        return run_ld(None, sys.argv[1:])


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