#!/usr/bin/env python

# SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD
# SPDX-License-Identifier: Apache-2.0

import argparse
import os
import sys

from . import (format_csv, format_json, format_json_tree, format_table,
               format_tree, log, memorymap)


def main() -> None:
    parser = argparse.ArgumentParser(prog='esp_idf_size.ng',
                                     description='This tool displays firmware size information for project built by ESP-IDF')

    parser.add_argument('input_file',
                        metavar='MAP_FILE',
                        help='Path to the link map file generated by the ESP-IDF build system.')

    format_group = parser.add_mutually_exclusive_group()
    format_group.add_argument('--format',
                              choices=['table', 'text', 'tree', 'csv', 'json', 'json-tree'],
                              default='table',
                              help='Specify output format: table(text), tree, csv, json or json-tree')

    parser.add_argument('--archives',
                        action='store_true',
                        help='Print per-archive sizes.')

    parser.add_argument('--archive-details', '--archive_details',
                        metavar='ARCHIVE_NAME',
                        help='Print detailed symbols per archive')

    parser.add_argument('--files',
                        action='store_true',
                        help='Print per-file sizes.')

    parser.add_argument('--diff',
                        metavar='MAP_FILE',
                        help='Compare sizes with another project.')

    parser.add_argument('--no-abbrev',
                        action='store_true',
                        help='Do not abbreviate section and file names.')

    parser.add_argument('--show-unused',
                        action='store_true',
                        help='Show unused memory types and sections.')

    parser.add_argument('--show-unchanged',
                        action='store_true',
                        help='Show unchanged items for --diff operation.')

    parser.add_argument('-d', '--debug',
                        action='store_true',
                        help=('Print debug information. Messages are printed to stderr.'))

    parser.add_argument('-o', '--output-file',
                        metavar='OUTPUT_FILE',
                        help=('Print output to the specified file instead of stdout.'))

    parser.add_argument('-q', '--quiet',
                        action='store_true',
                        help=('Suppress all output.'))

    parser.add_argument('--no-color',
                        action='store_true',
                        help=('Disable ANSI color escape sequences.'))

    parser.add_argument('--force-terminal',
                        action='store_true',
                        default=bool(os.environ.get('ESP_IDF_SIZE_FORCE_TERMINAL')) or None,
                        help=('Enable terminal control codes even if out is not attached to terminal.'))

    ofile = sys.stdout
    try:
        args = parser.parse_args()

        if args.output_file:
            ofile = open(args.output_file, 'w')

        log.set_console(ofile, args.quiet, args.no_color, args.force_terminal, args.debug)

        args.abbrev = not args.no_abbrev
        load_symbols = True if args.archive_details or args.format == 'json-tree' else False

        memmap = memorymap.get(args.input_file, load_symbols)
        if args.diff:
            memmap_ref = memorymap.get(args.diff, load_symbols)
            memmap = memorymap.diff(memmap, memmap_ref)
            if memmap['target'] != memmap['target_diff']:
                log.warn((f'The target of the reference and other project is '
                          f'{memmap["target"]} and {memmap["target_diff"]}, respectively.'))

        memorymap.trim(memmap, args)

        if args.format in ['table', 'text']:
            format_table.show(memmap, args)
        elif args.format == 'json':
            format_json.show(memmap, args)
        elif args.format == 'json-tree':
            format_json_tree.show(memmap, args)
        elif args.format == 'csv':
            format_csv.show(memmap, args)
        elif args.format == 'tree':
            format_tree.show(memmap, args)
    except KeyboardInterrupt:
        sys.exit(1)
    finally:
        if ofile:
            ofile.close()
