#!/usr/bin/env python3.8
# Copyright 2021 The Fuchsia Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
"""A helper script for generating a map of FIDL mangled C++ function names to fully qualified APIs.

The output of the script is used for correlating CTS C++ function coverage data
(keyed by mangled function names) to FIDL APIs.
"""

import argparse
import json
import os
import re
import subprocess
import sys

# FIDL method name annotation exists 1-line before declaration.
ANNOTATION_OFFSET = 1


class DwarfdumpStreamingParser:
    """Helper class to parse streaming output from `llvm-dwarfdump`."""

    DWARF_TAG_MATCHER = re.compile(r'^(0x\S+):\s+(\S+)')
    SUBPROGRAM_ATTR_MATCHER = re.compile(r'^\s+(\S+)\s+\((.+)\)')
    SUBPROGRAM_TAG = 'DW_TAG_subprogram'

    def __init__(self):
        # Instance variables to track parser state from line to line.
        self._cur_addr = None
        self._in_subprogram_block = False

        # Dict of compilation unit addresses to their respective attributes.
        self._subprograms_dict = {}

    def parse_line(self, line):
        """Parses a line from `llvm-dwarfdump`'s output.

        Args:
          line (string): A line of `llvm-dwarfdump` output.
        """
        if self._in_subprogram_block:
            m = self.SUBPROGRAM_ATTR_MATCHER.search(line)
            if m:
                attr, value = m.group(1), m.group(2)
                self._subprograms_dict[self._cur_addr][attr] = value
            else:
                # Dwarfdump entries are separated by a newline.
                # So the first unmatched line after entering a subprogram block
                # marks the end of the subprogram block.
                self._in_subprogram_block = False
            return

        m = self.DWARF_TAG_MATCHER.search(line)
        if m:
            addr, tag = m.group(1), m.group(2)
            if tag == self.SUBPROGRAM_TAG:
                self._in_subprogram_block = True
                self._cur_addr = addr
                self._subprograms_dict[self._cur_addr] = {}

    def get_subprograms(self):
        """Returns the subprograms that have been successfully parsed.

        Returns:
          A dict(string,dict) containing subprogram addresses and respective dwarfdump attributes.
        """
        return self._subprograms_dict


class FidlApiResolver:
    """Helper class to resolve mangled C++ function names to corresponding FIDL APIs.

    For each mangled C++ function that's associated with a `fidl.h` file,
    we use information provided in dwarfdump's output to navigate to where the function
    is declared in the generated source file (FIDL binding header file). Once there, we
    can simply read the Fully-Qualified FIDL API name annotation that's set a fixed number
    of lines above where the function is declared.

    Args:
      subprograms_dict (dict(string,dict)): Dict containing subprogram addresses and
        dwarfdump attributes.
      api_mapping_dict (dict(string,string)): Dict containing mapping between mangled
        function names and fully qualified FIDL names.
    """

    def __init__(self, subprograms_dict, api_mapping_dict):
        self._subprograms_dict = subprograms_dict
        self._api_mapping_dict = api_mapping_dict

    def add_new_mappings(self):
        """Add new mangled_name to FIDL API mapping if it doesn't already exist.

        New mappings are added to `self._api_mapping_dict`.
        """
        for _, info in self._subprograms_dict.items():
            # Only care about subprograms with file and line number information.
            if 'DW_AT_decl_file' not in info or 'DW_AT_decl_line' not in info:
                continue

            # Only process FIDL binding headers.
            if not info['DW_AT_decl_file'].endswith('fidl.h"'):
                continue

            mangled_name = info.get('DW_AT_linkage_name') or info.get(
                'DW_AT_name')
            if not mangled_name:
                # Ignore subprograms with no names.
                continue

            sanitized_mangled_name = mangled_name.strip('"')
            if sanitized_mangled_name not in self._api_mapping_dict:
                sanitized_filepath = info['DW_AT_decl_file'].strip('"')
                line_num = int(info['DW_AT_decl_line'])
                self._add_mapping_entry(
                    sanitized_mangled_name, sanitized_filepath, line_num)

    def _add_mapping_entry(self, mangled_name, filepath, line_num):
        """Resolve mangled_name to FIDL API mapping and add as mapping entry.

        Resolve mapping by opening the file where the function is defined, and reading
        an annotation that's a fixed-number of lines above the line of function declaration.

        Args:
          mangled_name (string): Mangled C++ function name to map to a FIDL API.
          filepath (string): Path to generated FIDL binding file that declares the function related
            to the `mangled_name`.
          line_num (int): The line number in the FIDL binding file where the function is declared.
        """
        fidl_api_annotation = ''
        cur_line = 0
        with open(filepath) as f:
            while cur_line != line_num - ANNOTATION_OFFSET:
                fidl_api_annotation = f.readline().strip()
                cur_line += 1
        if 'cts-coverage-fidl-name' not in fidl_api_annotation:
            # This is not a FIDL API of interest.
            return
        # Annotation format: "// cts-coverage-fidl-name:<API_NAME>"
        self._api_mapping_dict[mangled_name] = fidl_api_annotation.split(':')[1]

    def get_mapping(self):
        """Returns the mangled-name-to-FIDL-API mapping.

        Returns:
          A dict(str,str) containing mangled function names and their corresponding fully qualified
            FIDL API names.
        """
        return self._mapping


def main():
    parser = argparse.ArgumentParser()
    parser.add_argument(
        '--input',
        help=
        'File that contains filepaths to unstripped libraries & executables relative to the build dir.',
        required=True)
    parser.add_argument(
        '--output',
        help='Path to the output file containing FIDL to mangled name mapping.',
        required=True)
    parser.add_argument(
        '--depfile',
        help='Path to the depfile generated for GN.',
        required=True)
    parser.add_argument(
        '--dwarfdump',
        help='Path to `llvm-dwarfdump` executable.',
        required=True)
    args = parser.parse_args()

    depfile_inputs = []
    with open(args.input) as f:
        depfile_inputs = f.read().splitlines()

    # Write depfile.
    with open(args.depfile, 'w') as f:
        f.write('%s: %s' % (args.output, ' '.join(sorted(depfile_inputs))))

    # Generate mapping.
    fidl_mangled_name_to_api_mapping = {}
    for unstripped_binary in depfile_inputs:
        dwarddump_cmd = [args.dwarfdump, unstripped_binary]
        parser = DwarfdumpStreamingParser()
        # TODO(chok): Add multithreaded support for concurrently processing each unstripped binary.
        with subprocess.Popen(dwarddump_cmd, stdout=subprocess.PIPE) as p:
            for line in p.stdout:
                parser.parse_line(line.decode())
        resolver = FidlApiResolver(
            parser.get_subprograms(), fidl_mangled_name_to_api_mapping)
        resolver.add_new_mappings()

    # Write output.
    with open(args.output, 'w') as f:
        f.write(json.dumps(fidl_mangled_name_to_api_mapping, indent=2))


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