# Copyright 2022 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.
"""Size reporting utilities."""

import argparse
import logging
from pathlib import Path
import sys
from typing import Iterable

from pw_bloat import bloat
from pw_bloat.label import DataSourceMap
from pw_bloat.label_output import BloatTableOutput
import pw_cli.log

_LOG = logging.getLogger(__name__)


def _parse_args() -> argparse.Namespace:
    parser = argparse.ArgumentParser(description=__doc__)

    parser.add_argument(
        'binary',
        help='Path to the ELF file to analyze',
        metavar='BINARY',
        type=Path,
    )
    parser.add_argument(
        '-d',
        '--data-sources',
        help='Comma-separated list of Bloaty data sources to report',
        type=lambda s: s.split(','),
        default=('memoryregions,sections'),
    )
    parser.add_argument(
        '--diff',
        metavar='BINARY',
        help='Run a size diff against a base binary file',
        type=Path,
    )
    parser.add_argument(
        '-v',
        '--verbose',
        help=('Print all log messages ' '(only errors are printed by default)'),
        action='store_true',
    )

    return parser.parse_args()


def _run_size_report(
    elf: Path, data_sources: Iterable[str] = ()
) -> DataSourceMap:
    """Runs a size analysis on an ELF file, returning a pw_bloat size map.

    Returns:
        A size map of the labels in the binary under the provided data sources.

    Raises:
        NoMemoryRegions: The binary does not define bloat memory region symbols.
    """

    bloaty_tsv = bloat.memory_regions_size_report(
        elf, data_sources=data_sources, extra_args=('--tsv',)
    )

    return DataSourceMap.from_bloaty_tsv(bloaty_tsv)


def _no_memory_regions_error(elf: Path) -> None:
    _LOG.error('Executable %s does not define any bloat memory regions', elf)
    _LOG.error(
        'Refer to https://pigweed.dev/pw_bloat/#memoryregions-data-source'
    )
    _LOG.error('for information on how to configure them.')


def _single_binary_report(elf: Path, data_sources: Iterable[str] = ()) -> int:
    try:
        data_source_map = _run_size_report(elf, data_sources)
    except bloat.NoMemoryRegions:
        _no_memory_regions_error(elf)
        return 1

    print(BloatTableOutput(data_source_map).create_table())
    return 0


def _diff_report(
    target: Path, base: Path, data_sources: Iterable[str] = ()
) -> int:
    try:
        base_map = _run_size_report(base, data_sources)
        target_map = _run_size_report(target, data_sources)
    except bloat.NoMemoryRegions as err:
        _no_memory_regions_error(err.elf)
        return 1

    diff = target_map.diff(base_map)

    print(BloatTableOutput(diff).create_table())
    return 0


def main() -> int:
    """Run binary size reports."""

    args = _parse_args()

    if not args.verbose:
        pw_cli.log.set_all_loggers_minimum_level(logging.ERROR)

    if args.diff is not None:
        return _diff_report(
            args.binary, args.diff, data_sources=args.data_sources
        )

    return _single_binary_report(args.binary, data_sources=args.data_sources)


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