#!/usr/bin/env python3
#
# Copyright (c) 2021 Project CHIP 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
#
#     http://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.
#
"""
This is similar to scripts/tools/memory/report_summary.py, but generates
a specific output format with a simplified interface for use in github
workflows.

Usage: gh_sizes.py ‹platform› ‹config› ‹target› ‹binary› [‹output›] [‹option›…]
  ‹platform› - Platform name, corresponding to a config file
               in scripts/tools/memory/platform/
  ‹config›   - Configuration identification string.
  ‹target›   - Build artifact identification string.
  ‹binary›   - Binary build artifact.
  ‹output›   - Output name or directory.
  ‹option›…  - Other options as for report_summary.

This script also expects certain environment variables, which can be set in a
github workflow as follows:

    - name: Set up environment for size reports
      if: ${{ !env.ACT }}
      env:
        GH_CONTEXT: ${{ toJson(github) }}
      run: gh_sizes_environment.py "${GH_CONTEXT}"

Default output file is {platform}-{configname}-{buildname}-sizes.json in the
binary's directory. This file has the form:

  {
    "platform": "‹platform›",
    "config": "‹config›",
    "target": "‹target›",
    "time": 1317645296,
    "input": "‹binary›",
    "event": "pull_request",
    "hash": "496620796f752063616e20726561642074686973",
    "parent": "20796f752061726520746f6f20636c6f73652e0a",
    "pr": 12345,
    "by": "section",
    "ref": "refs/pull/12345/merge"
    "frames": {
        "section": [
          {"section": ".bss", "size": 260496},
          {"section": ".data", "size": 1648},
          {"section": ".text", "size": 740236}
        ],
        "wr": [
          {"wr": 0, "size": 262144},
          {"wr": 1, "size": 74023}
        ]
    }
  }

"""

import datetime
import logging
import os
import pathlib
import sys

import numpy as np  # type: ignore

import memdf.collect
import memdf.report
import memdf.select
import memdf.util

from memdf import Config, ConfigDescription, DFs, SectionDF, SegmentDF

PLATFORM_CONFIG_DIR = pathlib.Path('scripts/tools/memory/platform')

CONFIG: ConfigDescription = {
    'event': {
        'help': 'Github workflow event name',
        'metavar': 'NAME',
        'default': os.environ.get('GITHUB_EVENT_NAME'),
    },
    'pr': {
        'help': 'Github PR number',
        'metavar': 'NUMBER',
        'default': int(os.environ.get('GH_EVENT_PR', '0')),
    },
    'hash': {
        'help': 'Current commit hash',
        'metavar': 'HASH',
        'default': os.environ.get('GH_EVENT_HASH'),
    },
    'parent': {
        'help': 'Parent commit hash',
        'metavar': 'HASH',
        'default': os.environ.get('GH_EVENT_PARENT'),
    },
    'ref': {
        'help': 'Target ref',
        'metavar': 'REF',
        'default': os.environ.get('GH_EVENT_REF'),
    },
    'timestamp': {
        'help': 'Build timestamp',
        'metavar': 'TIME',
        'default': int(float(
            os.environ.get('GH_EVENT_TIMESTAMP')
            or datetime.datetime.now().timestamp())),
    },
}


def main(argv):
    status = 0

    try:
        _, platform, config_name, target_name, binary, *args = argv
    except ValueError:
        program = pathlib.Path(argv[0])
        logging.error(
            """
            Usage: %s platform config target binary [output] [options]

            This is intended for use in github workflows.
            For other purposes, a general program for the same operations is
            %s/report_summary.py

            """, program.name, program.parent)
        return 1

    try:
        config_file = pathlib.Path(platform)
        if config_file.is_file():
            platform = config_file.stem
        else:
            config_file = (PLATFORM_CONFIG_DIR / platform).with_suffix('.cfg')

        output_base = f'{platform}-{config_name}-{target_name}-sizes.json'
        if args and not args[0].startswith('-'):
            out, *args = args
            output = pathlib.Path(out)
            if out.endswith('/') and not output.exists():
                output.mkdir(parents=True)
            if output.is_dir():
                output = output / output_base
        else:
            output = pathlib.Path(binary).parent / output_base

        config = Config().init({
            **memdf.util.config.CONFIG,
            **memdf.collect.CONFIG,
            **memdf.select.CONFIG,
            **memdf.report.OUTPUT_CONFIG,
            **CONFIG,
        })
        config.put('output.file', output)
        config.put('output.format', 'json_records')
        if config_file.is_file():
            config.read_config_file(config_file)
        else:
            logging.warning('Missing config file: %s', config_file)
        config.parse([argv[0]] + args)

        config.put('output.metadata.platform', platform)
        config.put('output.metadata.config', config_name)
        config.put('output.metadata.target', target_name)
        config.put('output.metadata.time', config['timestamp'])
        config.put('output.metadata.input', binary)
        config.put('output.metadata.by', 'section')
        for key in ['event', 'hash', 'parent', 'pr', 'ref']:
            if value := config[key]:
                config.putl(['output', 'metadata', key], value)

        collected: DFs = memdf.collect.collect_files(config, [binary])

        # Aggregate loaded segments, by writable (flash) or not (RAM).
        segments = collected[SegmentDF.name]
        segments['segment'] = segments.index
        segments['wr'] = ((segments['flags'] & 2) != 0).convert_dtypes(
            convert_boolean=False, convert_integer=True)
        segment_summary = segments[segments['type'] == 'PT_LOAD'][[
            'wr', 'size'
        ]].groupby('wr').aggregate(np.sum).reset_index().astype(
            {'size': np.int64})
        segment_summary.attrs['name'] = "wr"

        sections = collected[SectionDF.name]
        sections = sections.join(on='segment',
                                 how='left',
                                 other=segments,
                                 rsuffix='-segment')
        section_summary = sections[['section', 'size',
                                    'wr']].sort_values(by='section')
        section_summary.attrs['name'] = "section"

        summaries = {
            'section': section_summary,
            'memory': segment_summary,
        }

        # Write configured (json) report to the output file.
        memdf.report.write_dfs(config, summaries)

        # Write text report to stdout.
        memdf.report.write_dfs(config,
                               summaries,
                               sys.stdout,
                               'simple',
                               floatfmt='.0f')

    except Exception as exception:
        raise exception

    return status


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