# Copyright 2019 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.
"""
bloat is a script which generates a size report card for binary files.
"""

import argparse
import os
import subprocess
import sys

from typing import List, Iterable, Optional

from binary_diff import BinaryDiff
import bloat_output


def parse_args() -> argparse.Namespace:
    """Parses the script's arguments."""
    def delimited_list(delimiter: str, items: Optional[int] = None):
        def _parser(arg: str):
            args = arg.split(delimiter)

            if items and len(args) != items:
                raise argparse.ArgumentTypeError(
                    'Argument must be a '
                    f'{delimiter}-delimited list with {items} items: "{arg}"')

            return args

        return _parser

    parser = argparse.ArgumentParser(
        'Generate a size report card for binaries')
    parser.add_argument('--bloaty-config',
                        type=str,
                        required=True,
                        help='Data source configuration for Bloaty')
    parser.add_argument('--full',
                        action='store_true',
                        help='Display full bloat breakdown by symbol')
    parser.add_argument('--labels',
                        type=delimited_list(';'),
                        default='',
                        help='Labels for output binaries')
    parser.add_argument('--out-dir',
                        type=str,
                        required=True,
                        help='Directory in which to write output files')
    parser.add_argument('--target',
                        type=str,
                        required=True,
                        help='Build target name')
    parser.add_argument('--title',
                        type=str,
                        default='pw_bloat',
                        help='Report title')
    parser.add_argument('--source-filter',
                        type=str,
                        help='Bloaty data source filter')
    parser.add_argument('diff_targets',
                        type=delimited_list(';', 2),
                        nargs='+',
                        metavar='DIFF_TARGET',
                        help='Binary;base pairs to process')

    return parser.parse_args()


def run_bloaty(filename: str,
               config: str,
               base_file: Optional[str] = None,
               data_sources: Iterable[str] = (),
               extra_args: Iterable[str] = ()) -> bytes:
    """Executes a Bloaty size report on some binary file(s).

    Args:
        filename: Path to the binary.
        config: Path to Bloaty config file.
        base_file: Path to a base binary. If provided, a size diff is performed.
        data_sources: List of Bloaty data sources for the report.
        extra_args: Additional command-line arguments to pass to Bloaty.

    Returns:
        Binary output of the Bloaty invocation.

    Raises:
        subprocess.CalledProcessError: The Bloaty invocation failed.
    """

    # TODO(frolv): Point the default bloaty path to a prebuilt in Pigweed.
    default_bloaty = 'bloaty'
    bloaty_path = os.getenv('BLOATY_PATH', default_bloaty)

    # yapf: disable
    cmd = [
        bloaty_path,
        '-c', config,
        '-d', ','.join(data_sources),
        '--domain', 'vm',
        filename,
        *extra_args
    ]
    # yapf: enable

    if base_file is not None:
        cmd.extend(['--', base_file])

    return subprocess.check_output(cmd)


def main() -> int:
    """Program entry point."""

    args = parse_args()

    base_binaries: List[str] = []
    diff_binaries: List[str] = []

    try:
        for binary, base in args.diff_targets:
            diff_binaries.append(binary)
            base_binaries.append(base)
    except RuntimeError as err:
        print(f'{sys.argv[0]}: {err}', file=sys.stderr)
        return 1

    data_sources = ['segment_names']
    if args.full:
        data_sources.append('fullsymbols')

    # TODO(frolv): CSV output is disabled for full reports as the default Bloaty
    # breakdown is printed. This script should be modified to print a custom
    # symbol breakdown in full reports.
    extra_args = [] if args.full else ['--csv']
    if args.source_filter:
        extra_args.extend(['--source-filter', args.source_filter])

    diffs: List[BinaryDiff] = []
    report = []

    for i, binary in enumerate(diff_binaries):
        binary_name = args.labels[i] if i < len(
            args.labels) else os.path.basename(binary)
        try:
            output = run_bloaty(binary, args.bloaty_config, base_binaries[i],
                                data_sources, extra_args)
            if not output:
                continue

            # TODO(frolv): Remove when custom output for full mode is added.
            if args.full:
                report.append(binary_name)
                report.append('-' * len(binary_name))
                report.append(output.decode())
                continue

            # Ignore the first row as it displays column names.
            bloaty_csv = output.decode().splitlines()[1:]
            diffs.append(BinaryDiff.from_csv(binary_name, bloaty_csv))
        except subprocess.CalledProcessError:
            print(f'{sys.argv[0]}: failed to run diff on {binary}',
                  file=sys.stderr)

    def write_file(filename: str, contents: str) -> None:
        path = os.path.join(args.out_dir, filename)
        with open(path, 'w') as output_file:
            output_file.write(contents)
        print(f'Output written to {path}')

    # TODO(frolv): Remove when custom output for full mode is added.
    if not args.full:
        out = bloat_output.TableOutput(args.title,
                                       diffs,
                                       charset=bloat_output.LineCharset)
        report.append(out.diff())

        rst = bloat_output.RstOutput(diffs)
        write_file(f'{args.target}.rst', rst.diff())

    complete_output = '\n'.join(report) + '\n'
    write_file(f'{args.target}.txt', complete_output)
    print(complete_output)

    return 0


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