#!/usr/bin/python3
#
# Script for comparing buildstats from two different builds
#
# Copyright (c) 2016, Intel Corporation.
#
# SPDX-License-Identifier: GPL-2.0-only
#

import argparse
import glob
import logging
import math
import os
import sys
from operator import attrgetter

# Import oe libs
scripts_path = os.path.dirname(os.path.realpath(__file__))
sys.path.append(os.path.join(scripts_path, 'lib'))
from buildstats import BuildStats, diff_buildstats, taskdiff_fields, BSVerDiff


# Setup logging
logging.basicConfig(level=logging.INFO, format="%(levelname)s: %(message)s")
log = logging.getLogger()


class ScriptError(Exception):
    """Exception for internal error handling of this script"""
    pass


def read_buildstats(path, multi):
    """Read buildstats"""
    if not os.path.exists(path):
        raise ScriptError("No such file or directory: {}".format(path))

    if os.path.isfile(path):
        return BuildStats.from_file_json(path)

    if os.path.isfile(os.path.join(path, 'build_stats')):
        return BuildStats.from_dir(path)

    # Handle a non-buildstat directory
    subpaths = sorted(glob.glob(path + '/*'))
    if len(subpaths) > 1:
        if multi:
            log.info("Averaging over {} buildstats from {}".format(
                     len(subpaths), path))
        else:
            raise ScriptError("Multiple buildstats found in '{}'. Please give "
                              "a single buildstat directory of use the --multi "
                              "option".format(path))
    bs = None
    for subpath in subpaths:
        if os.path.isfile(subpath):
            _bs = BuildStats.from_file_json(subpath)
        else:
            _bs = BuildStats.from_dir(subpath)
        if bs is None:
            bs = _bs
        else:
            bs.aggregate(_bs)
    if not bs:
        raise ScriptError("No buildstats found under {}".format(path))

    return bs


def print_ver_diff(bs1, bs2):
    """Print package version differences"""

    diff = BSVerDiff(bs1, bs2)

    maxlen = max([len(r) for r in set(bs1.keys()).union(set(bs2.keys()))])
    fmt_str = "  {:{maxlen}} ({})"

    if diff.new:
        print("\nNEW RECIPES:")
        print("------------")
        for name, val in sorted(diff.new.items()):
            print(fmt_str.format(name, val.nevr, maxlen=maxlen))

    if diff.dropped:
        print("\nDROPPED RECIPES:")
        print("----------------")
        for name, val in sorted(diff.dropped.items()):
            print(fmt_str.format(name, val.nevr, maxlen=maxlen))

    fmt_str = "  {0:{maxlen}} {1:<20}    ({2})"
    if diff.rchanged:
        print("\nREVISION CHANGED:")
        print("-----------------")
        for name, val in sorted(diff.rchanged.items()):
            field1 = "{} -> {}".format(val.left.revision, val.right.revision)
            field2 = "{} -> {}".format(val.left.nevr, val.right.nevr)
            print(fmt_str.format(name, field1, field2, maxlen=maxlen))

    if diff.vchanged:
        print("\nVERSION CHANGED:")
        print("----------------")
        for name, val in sorted(diff.vchanged.items()):
            field1 = "{} -> {}".format(val.left.version, val.right.version)
            field2 = "{} -> {}".format(val.left.nevr, val.right.nevr)
            print(fmt_str.format(name, field1, field2, maxlen=maxlen))

    if diff.echanged:
        print("\nEPOCH CHANGED:")
        print("--------------")
        for name, val in sorted(diff.echanged.items()):
            field1 = "{} -> {}".format(val.left.epoch, val.right.epoch)
            field2 = "{} -> {}".format(val.left.nevr, val.right.nevr)
            print(fmt_str.format(name, field1, field2, maxlen=maxlen))


def print_task_diff(bs1, bs2, val_type, min_val=0, min_absdiff=0, sort_by=('absdiff',), only_tasks=[]):
    """Diff task execution times"""
    def val_to_str(val, human_readable=False):
        """Convert raw value to printable string"""
        def hms_time(secs):
            """Get time in human-readable HH:MM:SS format"""
            h = int(secs / 3600)
            m = int((secs % 3600) / 60)
            s = secs % 60
            if h == 0:
                return "{:02d}:{:04.1f}".format(m, s)
            else:
                return "{:d}:{:02d}:{:04.1f}".format(h, m, s)

        if 'time' in val_type:
            if human_readable:
                return hms_time(val)
            else:
                return "{:.1f}s".format(val)
        elif 'bytes' in val_type and human_readable:
                prefix = ['', 'Ki', 'Mi', 'Gi', 'Ti', 'Pi']
                dec = int(math.log(val, 2) / 10)
                prec = 1 if dec > 0 else 0
                return "{:.{prec}f}{}B".format(val / (2 ** (10 * dec)),
                                               prefix[dec], prec=prec)
        elif 'ops' in val_type and human_readable:
                prefix = ['', 'k', 'M', 'G', 'T', 'P']
                dec = int(math.log(val, 1000))
                prec = 1 if dec > 0 else 0
                return "{:.{prec}f}{}ops".format(val / (1000 ** dec),
                                                 prefix[dec], prec=prec)
        return str(int(val))

    def sum_vals(buildstats):
        """Get cumulative sum of all tasks"""
        total = 0.0
        for recipe_data in buildstats.values():
            for name, bs_task in recipe_data.tasks.items():
                if not only_tasks or name in only_tasks:
                    total += getattr(bs_task, val_type)
        return total

    if min_val:
        print("Ignoring tasks less than {} ({})".format(
                val_to_str(min_val, True), val_to_str(min_val)))
    if min_absdiff:
        print("Ignoring differences less than {} ({})".format(
                val_to_str(min_absdiff, True), val_to_str(min_absdiff)))

    # Prepare the data
    tasks_diff = diff_buildstats(bs1, bs2, val_type, min_val, min_absdiff, only_tasks)

    # Sort our list
    for field in reversed(sort_by):
        if field.startswith('-'):
            field = field[1:]
            reverse = True
        else:
            reverse = False
        tasks_diff = sorted(tasks_diff, key=attrgetter(field), reverse=reverse)

    linedata = [('  ', 'PKG', '  ', 'TASK', 'ABSDIFF', 'RELDIFF',
                val_type.upper() + '1', val_type.upper() + '2')]
    field_lens = dict([('len_{}'.format(i), len(f)) for i, f in enumerate(linedata[0])])

    # Prepare fields in string format and measure field lengths
    for diff in tasks_diff:
        task_prefix = diff.task_op if diff.pkg_op == '  ' else '  '
        linedata.append((diff.pkg_op, diff.pkg, task_prefix, diff.task,
                         val_to_str(diff.absdiff),
                         '{:+.1f}%'.format(diff.reldiff),
                         val_to_str(diff.value1),
                         val_to_str(diff.value2)))
        for i, field in enumerate(linedata[-1]):
            key = 'len_{}'.format(i)
            if len(field) > field_lens[key]:
                field_lens[key] = len(field)

    # Print data
    print()
    for fields in linedata:
        print("{:{len_0}}{:{len_1}}  {:{len_2}}{:{len_3}}  {:>{len_4}}  {:>{len_5}}  {:>{len_6}} -> {:{len_7}}".format(
                *fields, **field_lens))

    # Print summary of the diffs
    total1 = sum_vals(bs1)
    total2 = sum_vals(bs2)
    print("\nCumulative {}:".format(val_type))
    print ("  {}    {:+.1f}%    {} ({}) -> {} ({})".format(
                val_to_str(total2 - total1), 100 * (total2-total1) / total1,
                val_to_str(total1, True), val_to_str(total1),
                val_to_str(total2, True), val_to_str(total2)))


def parse_args(argv):
    """Parse cmdline arguments"""
    description="""
Script for comparing buildstats of two separate builds."""
    parser = argparse.ArgumentParser(
            formatter_class=argparse.ArgumentDefaultsHelpFormatter,
            description=description)

    min_val_defaults = {'cputime': 3.0,
                        'read_bytes': 524288,
                        'write_bytes': 524288,
                        'read_ops': 500,
                        'write_ops': 500,
                        'walltime': 5}
    min_absdiff_defaults = {'cputime': 1.0,
                            'read_bytes': 131072,
                            'write_bytes': 131072,
                            'read_ops': 50,
                            'write_ops': 50,
                            'walltime': 2}

    parser.add_argument('--debug', '-d', action='store_true',
                        help="Verbose logging")
    parser.add_argument('--ver-diff', action='store_true',
                        help="Show package version differences and exit")
    parser.add_argument('--diff-attr', default='cputime',
                        choices=min_val_defaults.keys(),
                        help="Buildstat attribute which to compare")
    parser.add_argument('--min-val', default=min_val_defaults, type=float,
                        help="Filter out tasks less than MIN_VAL. "
                             "Default depends on --diff-attr.")
    parser.add_argument('--min-absdiff', default=min_absdiff_defaults, type=float,
                        help="Filter out tasks whose difference is less than "
                             "MIN_ABSDIFF, Default depends on --diff-attr.")
    parser.add_argument('--sort-by', default='absdiff',
                        help="Comma-separated list of field sort order. "
                             "Prepend the field name with '-' for reversed sort. "
                             "Available fields are: {}".format(', '.join(taskdiff_fields)))
    parser.add_argument('--multi', action='store_true',
                        help="Read all buildstats from the given paths and "
                             "average over them")
    parser.add_argument('--only-task', dest='only_tasks', metavar='TASK', action='append', default=[],
                        help="Only include TASK in report. May be specified multiple times")
    parser.add_argument('buildstats1', metavar='BUILDSTATS1', help="'Left' buildstat")
    parser.add_argument('buildstats2', metavar='BUILDSTATS2', help="'Right' buildstat")

    args = parser.parse_args(argv)

    # We do not nedd/want to read all buildstats if we just want to look at the
    # package versions
    if args.ver_diff:
        args.multi = False

    # Handle defaults for the filter arguments
    if args.min_val is min_val_defaults:
        args.min_val = min_val_defaults[args.diff_attr]
    if args.min_absdiff is min_absdiff_defaults:
        args.min_absdiff = min_absdiff_defaults[args.diff_attr]

    return args

def main(argv=None):
    """Script entry point"""
    args = parse_args(argv)
    if args.debug:
        log.setLevel(logging.DEBUG)

    # Validate sort fields
    sort_by = []
    for field in args.sort_by.split(','):
        if field.lstrip('-') not in taskdiff_fields:
            log.error("Invalid sort field '%s' (must be one of: %s)" %
                      (field, ', '.join(taskdiff_fields)))
            sys.exit(1)
        sort_by.append(field)

    try:
        bs1 = read_buildstats(args.buildstats1, args.multi)
        bs2 = read_buildstats(args.buildstats2, args.multi)

        if args.ver_diff:
            print_ver_diff(bs1, bs2)
        else:
            print_task_diff(bs1, bs2, args.diff_attr, args.min_val,
                            args.min_absdiff, sort_by, args.only_tasks)
    except ScriptError as err:
        log.error(str(err))
        return 1
    return 0

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