#!/usr/bin/env python3
#
# Dump a summary of the specified buildstats to the terminal, filtering and
# sorting by walltime.
#
# SPDX-License-Identifier: GPL-2.0-only

import argparse
import dataclasses
import datetime
import enum
import os
import pathlib
import sys

scripts_path = os.path.dirname(os.path.realpath(__file__))
sys.path.append(os.path.join(scripts_path, "lib"))
import buildstats


@dataclasses.dataclass
class Task:
    recipe: str
    task: str
    start: datetime.datetime
    duration: datetime.timedelta


class Sorting(enum.Enum):
    start = 1
    duration = 2

    # argparse integration
    def __str__(self) -> str:
        return self.name

    def __repr__(self) -> str:
        return self.name

    @staticmethod
    def from_string(s: str):
        try:
            return Sorting[s]
        except KeyError:
            return s


def read_buildstats(path: pathlib.Path) -> buildstats.BuildStats:
    if not path.exists():
        raise Exception(f"No such file or directory: {path}")
    if path.is_file():
        return buildstats.BuildStats.from_file_json(path)
    if (path / "build_stats").is_file():
        return buildstats.BuildStats.from_dir(path)
    raise Exception(f"Cannot find buildstats in {path}")


def dump_buildstats(args, bs: buildstats.BuildStats):
    tasks = []
    for recipe in bs.values():
        for task, stats in recipe.tasks.items():
            t = Task(
                recipe.name,
                task,
                datetime.datetime.fromtimestamp(stats["start_time"]),
                datetime.timedelta(seconds=int(stats.walltime)),
            )
            tasks.append(t)

    tasks.sort(key=lambda t: getattr(t, args.sort.name))

    minimum = datetime.timedelta(seconds=args.shortest)
    highlight = datetime.timedelta(seconds=args.highlight)

    for t in tasks:
        if t.duration >= minimum:
            line = f"{t.duration}    {t.recipe}:{t.task}"
            if args.highlight and t.duration >= highlight:
                print(f"\033[1m{line}\033[0m")
            else:
                print(line)


def main(argv=None) -> int:
    parser = argparse.ArgumentParser(
        formatter_class=argparse.ArgumentDefaultsHelpFormatter
    )

    parser.add_argument(
        "buildstats", metavar="BUILDSTATS", help="Buildstats file", type=pathlib.Path
    )
    parser.add_argument(
        "--sort",
        "-s",
        type=Sorting.from_string,
        choices=list(Sorting),
        default=Sorting.start,
        help="Sort tasks",
    )
    parser.add_argument(
        "--shortest",
        "-t",
        type=int,
        default=1,
        metavar="SECS",
        help="Hide tasks shorter than SECS seconds",
    )
    parser.add_argument(
        "--highlight",
        "-g",
        type=int,
        default=60,
        metavar="SECS",
        help="Highlight tasks longer than SECS seconds (0 disabled)",
    )

    args = parser.parse_args(argv)

    bs = read_buildstats(args.buildstats)
    dump_buildstats(args, bs)

    return 0


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