#!/usr/bin/env python3
# Copyright 2021 The Pigweed Authors
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may not
# use this file except in compliance with the License. You may obtain a copy of
# the License at
#
#     https://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations under
# the License.
"""Generates flags needed for an ARM build using clang.

Using clang on Cortex-M cores isn't intuitive as the end-to-end experience isn't
quite completely in LLVM. LLVM doesn't yet provide compatible C runtime
libraries or C/C++ standard libraries. To work around this, this script pulls
the missing bits from an arm-none-eabi-gcc compiler on the system path. This
lets clang do the heavy lifting while only relying on some headers provided by
newlib/arm-none-eabi-gcc in addition to a small assortment of needed libraries.

To use this script, specify what flags you want from the script, and run with
the required architecture flags like you would with gcc:

  python -m pw_toolchain.clang_arm_toolchain --cflags -- -mthumb -mcpu=cortex-m3

The script will then print out the additional flags you need to pass to clang to
get a working build.
"""

import argparse
import sys
import subprocess

from pathlib import Path
from typing import List, Dict, Tuple

_ARM_COMPILER_PREFIX = 'arm-none-eabi'
_ARM_COMPILER_NAME = _ARM_COMPILER_PREFIX + '-gcc'


def _parse_args() -> argparse.Namespace:
    """Parses arguments for this script, splitting out the command to run."""

    parser = argparse.ArgumentParser(description=__doc__)
    parser.add_argument(
        '--gn-scope',
        action='store_true',
        help=("Formats the output like a GN scope so it can be ingested by "
              "exec_script()"))
    parser.add_argument('--cflags',
                        action='store_true',
                        help=('Include necessary C flags in the output'))
    parser.add_argument('--ldflags',
                        action='store_true',
                        help=('Include necessary linker flags in the output'))
    parser.add_argument(
        'clang_flags',
        nargs=argparse.REMAINDER,
        help='Flags to pass to clang, which can affect library/include paths',
    )
    parsed_args = parser.parse_args()

    assert parsed_args.clang_flags[0] == '--', 'arguments not correctly split'
    parsed_args.clang_flags = parsed_args.clang_flags[1:]
    return parsed_args


def _compiler_info_command(print_command: str, cflags: List[str]) -> str:
    command = [_ARM_COMPILER_NAME]
    command.extend(cflags)
    command.append(print_command)
    result = subprocess.run(
        command,
        stdout=subprocess.PIPE,
        stderr=subprocess.STDOUT,
    )
    result.check_returncode()
    return result.stdout.decode().rstrip()


def get_gcc_lib_dir(cflags: List[str]) -> Path:
    return Path(_compiler_info_command('-print-libgcc-file-name',
                                       cflags)).parent


def get_compiler_info(cflags: List[str]) -> Dict[str, str]:
    compiler_info: Dict[str, str] = {}
    compiler_info['gcc_libs_dir'] = str(get_gcc_lib_dir(cflags))
    compiler_info['sysroot'] = _compiler_info_command('-print-sysroot', cflags)
    compiler_info['version'] = _compiler_info_command('-dumpversion', cflags)
    compiler_info['multi_dir'] = _compiler_info_command(
        '-print-multi-directory', cflags)
    return compiler_info


def get_cflags(compiler_info: Dict[str, str]):
    # TODO(amontanez): Make newlib-nano optional.
    cflags = [
        # TODO(amontanez): For some reason, -stdlib++-isystem and
        # -isystem-after work, but emit unused argument errors. This is the only
        # way to let the build succeed.
        '-Qunused-arguments',
        # Disable all default libraries.
        "-nodefaultlibs",
        '--target=arm-none-eabi'
    ]

    # Add sysroot info.
    cflags.extend((
        '--sysroot=' + compiler_info['sysroot'],
        '-isystem' +
        str(Path(compiler_info['sysroot']) / 'include' / 'newlib-nano'),
        # This must be included after Clang's builtin headers.
        '-isystem-after' + str(Path(compiler_info['sysroot']) / 'include'),
        '-stdlib++-isystem' + str(
            Path(compiler_info['sysroot']) / 'include' / 'c++' /
            compiler_info['version']),
        '-isystem' + str(
            Path(compiler_info['sysroot']) / 'include' / 'c++' /
            compiler_info['version'] / _ARM_COMPILER_PREFIX /
            compiler_info['multi_dir']),
    ))

    return cflags


def get_crt_objs(compiler_info: Dict[str, str]) -> Tuple[str, ...]:
    return (
        str(Path(compiler_info['gcc_libs_dir']) / 'crtfastmath.o'),
        str(Path(compiler_info['gcc_libs_dir']) / 'crti.o'),
        str(Path(compiler_info['gcc_libs_dir']) / 'crtn.o'),
        str(
            Path(compiler_info['sysroot']) / 'lib' /
            compiler_info['multi_dir'] / 'crt0.o'),
    )


def get_ldflags(compiler_info: Dict[str, str]) -> List[str]:
    ldflags: List[str] = [
        '-lnosys',
        # Add library search paths.
        '-L' + compiler_info['gcc_libs_dir'],
        '-L' + str(
            Path(compiler_info['sysroot']) / 'lib' /
            compiler_info['multi_dir']),
        # Add libraries to link.
        '-lc_nano',
        '-lm',
        '-lgcc',
        '-lstdc++_nano',
    ]

    # Add C runtime object files.
    objs = get_crt_objs(compiler_info)
    ldflags.extend(objs)

    return ldflags


def main(
    cflags: bool,
    ldflags: bool,
    gn_scope: bool,
    clang_flags: List[str],
) -> int:
    """Script entry point."""
    compiler_info = get_compiler_info(clang_flags)
    if ldflags:
        ldflag_list = get_ldflags(compiler_info)

    if cflags:
        cflag_list = get_cflags(compiler_info)

    if not gn_scope:
        flags = []
        if cflags:
            flags.extend(cflag_list)
        if ldflags:
            flags.extend(ldflag_list)
        print(' '.join(flags))
        return 0

    if cflags:
        print('cflags = [')
        for flag in cflag_list:
            print(f'  "{flag}",')
        print(']')

    if ldflags:
        print('ldflags = [')
        for flag in ldflag_list:
            print(f'  "{flag}",')
        print(']')
    return 0


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