#!/usr/bin/env python3
# Copyright (c) 2021 Intel Corporation
#
# SPDX-License-Identifier: Apache-2.0

# A script to diff between two ram or rom reports generated by
# size_report. When you call call the ram_report or rom_report targets you
# end up with a json file in the build directory that can be used as input
# for this script.

# The output shows which symbols increased and which decreased in size and
# also tracked added/remove symbols as well.

# Example:
#    ./scripts/footprint/fpdiff.py ram1.json ram2.json

from anytree.importer import DictImporter
from anytree import PreOrderIter, AnyNode
from anytree.search  import find

import colorama
from colorama import Fore
import json
import argparse

importer = DictImporter()

def parse_args():
    parser = argparse.ArgumentParser(
                description="Compare footprint sizes of two builds.", allow_abbrev=False)
    parser.add_argument("file1", help="First file")
    parser.add_argument("file2", help="Second file")

    return parser.parse_args()

def main():
    colorama.init()

    args = parse_args()

    with open(args.file1, "r") as f:
        data1 = json.load(f)

    with open(args.file2, "r") as f:
        data2 = json.load(f)

    for idx, ch in enumerate(data1['symbols']['children']):
        root1 = importer.import_(ch)
        if idx >= len(data2['symbols']['children']):
            root2 = AnyNode(identifier=None)
        else:
            root2 = importer.import_(data2['symbols']['children'][idx])
        print(f"{root1.name}\n+++++++++++++++++++++")

        for node in PreOrderIter(root1):
            # pylint: disable=undefined-loop-variable
            n = find(root2, lambda node2: node2.identifier == node.identifier)
            if n:
                if n.size != node.size:
                    diff = n.size - node.size
                    if diff == 0:
                        continue
                    if not n.children or not n.parent:
                        if diff < 0:
                            print(f"{n.identifier} -> {Fore.GREEN}{diff}{Fore.RESET}")
                        else:
                            print(f"{n.identifier} -> {Fore.RED}+{diff}{Fore.RESET}")

            else:
                if not node.children:
                    print(f"{node.identifier} ({Fore.GREEN}-{node.size}{Fore.RESET}) disappeared.")

        for node in PreOrderIter(root2):
            n = find(root1, lambda node2: node2.identifier == node.identifier)
            if not n:
                if not node.children and node.size != 0:
                    print(f"{node.identifier} ({Fore.RED}+{node.size}{Fore.RESET}) is new.")


if __name__ == "__main__":
    main()
