"""Print a summary of specialization stats for all files in the
default stats folders.
"""

# NOTE: Bytecode introspection modules (opcode, dis, etc.) should only
# happen when loading a single dataset. When comparing datasets, it
# could get it wrong, leading to subtle errors.

import argparse
import collections
import json
import os.path
from datetime import date
import itertools
import sys
import re

if os.name == "nt":
    DEFAULT_DIR = "c:\\temp\\py_stats\\"
else:
    DEFAULT_DIR = "/tmp/py_stats/"

TOTAL = "specialization.hit", "specialization.miss", "execution_count"


def format_ratio(num, den):
    """
    Format a ratio as a percentage. When the denominator is 0, returns the empty
    string.
    """
    if den == 0:
        return ""
    else:
        return f"{num/den:.01%}"


def percentage_to_float(s):
    """
    Converts a percentage string to a float.  The empty string is returned as 0.0
    """
    if s == "":
        return 0.0
    else:
        assert s[-1] == "%"
        return float(s[:-1])


def join_rows(a_rows, b_rows):
    """
    Joins two tables together, side-by-side, where the first column in each is a
    common key.
    """
    if len(a_rows) == 0 and len(b_rows) == 0:
        return []

    if len(a_rows):
        a_ncols = list(set(len(x) for x in a_rows))
        if len(a_ncols) != 1:
            raise ValueError("Table a is ragged")

    if len(b_rows):
        b_ncols = list(set(len(x) for x in b_rows))
        if len(b_ncols) != 1:
            raise ValueError("Table b is ragged")

    if len(a_rows) and len(b_rows) and a_ncols[0] != b_ncols[0]:
        raise ValueError("Tables have different widths")

    if len(a_rows):
        ncols = a_ncols[0]
    else:
        ncols = b_ncols[0]

    default = [""] * (ncols - 1)
    a_data = {x[0]: x[1:] for x in a_rows}
    b_data = {x[0]: x[1:] for x in b_rows}

    if len(a_data) != len(a_rows) or len(b_data) != len(b_rows):
        raise ValueError("Duplicate keys")

    # To preserve ordering, use A's keys as is and then add any in B that aren't
    # in A
    keys = list(a_data.keys()) + [k for k in b_data.keys() if k not in a_data]
    return [(k, *a_data.get(k, default), *b_data.get(k, default)) for k in keys]


def calculate_specialization_stats(family_stats, total):
    rows = []
    for key in sorted(family_stats):
        if key.startswith("specialization.failure_kinds"):
            continue
        if key in ("specialization.hit", "specialization.miss"):
            label = key[len("specialization.") :]
        elif key == "execution_count":
            continue
        elif key in (
            "specialization.success",
            "specialization.failure",
            "specializable",
        ):
            continue
        elif key.startswith("pair"):
            continue
        else:
            label = key
        rows.append(
            (
                f"{label:>12}",
                f"{family_stats[key]:>12}",
                format_ratio(family_stats[key], total),
            )
        )
    return rows


def calculate_specialization_success_failure(family_stats):
    total_attempts = 0
    for key in ("specialization.success", "specialization.failure"):
        total_attempts += family_stats.get(key, 0)
    rows = []
    if total_attempts:
        for key in ("specialization.success", "specialization.failure"):
            label = key[len("specialization.") :]
            label = label[0].upper() + label[1:]
            val = family_stats.get(key, 0)
            rows.append((label, val, format_ratio(val, total_attempts)))
    return rows


def calculate_specialization_failure_kinds(name, family_stats, defines):
    total_failures = family_stats.get("specialization.failure", 0)
    failure_kinds = [0] * 40
    for key in family_stats:
        if not key.startswith("specialization.failure_kind"):
            continue
        _, index = key[:-1].split("[")
        index = int(index)
        failure_kinds[index] = family_stats[key]
    failures = [(value, index) for (index, value) in enumerate(failure_kinds)]
    failures.sort(reverse=True)
    rows = []
    for value, index in failures:
        if not value:
            continue
        rows.append(
            (
                kind_to_text(index, defines, name),
                value,
                format_ratio(value, total_failures),
            )
        )
    return rows


def print_specialization_stats(name, family_stats, defines):
    if "specializable" not in family_stats:
        return
    total = sum(family_stats.get(kind, 0) for kind in TOTAL)
    if total == 0:
        return
    with Section(name, 3, f"specialization stats for {name} family"):
        rows = calculate_specialization_stats(family_stats, total)
        emit_table(("Kind", "Count", "Ratio"), rows)
        rows = calculate_specialization_success_failure(family_stats)
        if rows:
            print_title("Specialization attempts", 4)
            emit_table(("", "Count:", "Ratio:"), rows)
            rows = calculate_specialization_failure_kinds(name, family_stats, defines)
            emit_table(("Failure kind", "Count:", "Ratio:"), rows)


def print_comparative_specialization_stats(
    name, base_family_stats, head_family_stats, defines
):
    if "specializable" not in base_family_stats:
        return

    base_total = sum(base_family_stats.get(kind, 0) for kind in TOTAL)
    head_total = sum(head_family_stats.get(kind, 0) for kind in TOTAL)
    if base_total + head_total == 0:
        return
    with Section(name, 3, f"specialization stats for {name} family"):
        base_rows = calculate_specialization_stats(base_family_stats, base_total)
        head_rows = calculate_specialization_stats(head_family_stats, head_total)
        emit_table(
            ("Kind", "Base Count", "Base Ratio", "Head Count", "Head Ratio"),
            join_rows(base_rows, head_rows),
        )
        base_rows = calculate_specialization_success_failure(base_family_stats)
        head_rows = calculate_specialization_success_failure(head_family_stats)
        rows = join_rows(base_rows, head_rows)
        if rows:
            print_title("Specialization attempts", 4)
            emit_table(
                ("", "Base Count:", "Base Ratio:", "Head Count:", "Head Ratio:"), rows
            )
            base_rows = calculate_specialization_failure_kinds(
                name, base_family_stats, defines
            )
            head_rows = calculate_specialization_failure_kinds(
                name, head_family_stats, defines
            )
            emit_table(
                (
                    "Failure kind",
                    "Base Count:",
                    "Base Ratio:",
                    "Head Count:",
                    "Head Ratio:",
                ),
                join_rows(base_rows, head_rows),
            )


def gather_stats(input):
    # Note the output of this function must be JSON-serializable

    if os.path.isfile(input):
        with open(input, "r") as fd:
            stats = json.load(fd)

        stats["_stats_defines"] = {
            int(k): v for k, v in stats["_stats_defines"].items()
        }
        stats["_defines"] = {int(k): v for k, v in stats["_defines"].items()}
        return stats

    elif os.path.isdir(input):
        stats = collections.Counter()
        for filename in os.listdir(input):
            with open(os.path.join(input, filename)) as fd:
                for line in fd:
                    try:
                        key, value = line.split(":")
                    except ValueError:
                        print(
                            f"Unparsable line: '{line.strip()}' in  {filename}",
                            file=sys.stderr,
                        )
                        continue
                    key = key.strip()
                    value = int(value)
                    stats[key] += value
            stats["__nfiles__"] += 1

        import opcode

        stats["_specialized_instructions"] = [
            op for op in opcode._specialized_opmap.keys() if "__" not in op
        ]
        stats["_stats_defines"] = get_stats_defines()
        stats["_defines"] = get_defines()

        return stats
    else:
        raise ValueError(f"{input:r} is not a file or directory path")


def extract_opcode_stats(stats, prefix):
    opcode_stats = collections.defaultdict(dict)
    for key, value in stats.items():
        if not key.startswith(prefix):
            continue
        name, _, rest = key[len(prefix) + 1 :].partition("]")
        opcode_stats[name][rest.strip(".")] = value
    return opcode_stats


def parse_kinds(spec_src, prefix="SPEC_FAIL"):
    defines = collections.defaultdict(list)
    start = "#define " + prefix + "_"
    for line in spec_src:
        line = line.strip()
        if not line.startswith(start):
            continue
        line = line[len(start) :]
        name, val = line.split()
        defines[int(val.strip())].append(name.strip())
    return defines


def pretty(defname):
    return defname.replace("_", " ").lower()


def kind_to_text(kind, defines, opname):
    if kind <= 8:
        return pretty(defines[kind][0])
    if opname == "LOAD_SUPER_ATTR":
        opname = "SUPER"
    elif opname.endswith("ATTR"):
        opname = "ATTR"
    elif opname in ("FOR_ITER", "SEND"):
        opname = "ITER"
    elif opname.endswith("SUBSCR"):
        opname = "SUBSCR"
    for name in defines[kind]:
        if name.startswith(opname):
            return pretty(name[len(opname) + 1 :])
    return "kind " + str(kind)


def categorized_counts(opcode_stats, specialized_instructions):
    basic = 0
    specialized = 0
    not_specialized = 0
    for name, opcode_stat in opcode_stats.items():
        if "execution_count" not in opcode_stat:
            continue
        count = opcode_stat["execution_count"]
        if "specializable" in opcode_stat:
            not_specialized += count
        elif name in specialized_instructions:
            miss = opcode_stat.get("specialization.miss", 0)
            not_specialized += miss
            specialized += count - miss
        else:
            basic += count
    return basic, not_specialized, specialized


def print_title(name, level=2):
    print("#" * level, name)
    print()


class Section:
    def __init__(self, title, level=2, summary=None):
        self.title = title
        self.level = level
        if summary is None:
            self.summary = title.lower()
        else:
            self.summary = summary

    def __enter__(self):
        print_title(self.title, self.level)
        print("<details>")
        print("<summary>", self.summary, "</summary>")
        print()
        return self

    def __exit__(*args):
        print()
        print("</details>")
        print()


def to_str(x):
    if isinstance(x, int):
        return format(x, ",d")
    else:
        return str(x)


def emit_table(header, rows):
    width = len(header)
    header_line = "|"
    under_line = "|"
    for item in header:
        under = "---"
        if item.endswith(":"):
            item = item[:-1]
            under += ":"
        header_line += item + " | "
        under_line += under + "|"
    print(header_line)
    print(under_line)
    for row in rows:
        if width is not None and len(row) != width:
            raise ValueError("Wrong number of elements in row '" + str(row) + "'")
        print("|", " | ".join(to_str(i) for i in row), "|")
    print()


def emit_histogram(title, stats, key, total):
    rows = []
    for k, v in stats.items():
        if k.startswith(key):
            entry = int(re.match(r".+\[([0-9]+)\]", k).groups()[0])
            rows.append((f"<= {entry}", int(v), format_ratio(int(v), total)))
    # Don't include larger buckets with 0 entries
    for j in range(len(rows) - 1, -1, -1):
        if rows[j][1] != 0:
            break
    rows = rows[: j + 1]

    print(f"**{title}**\n")
    emit_table(("Range", "Count:", "Ratio:"), rows)


def calculate_execution_counts(opcode_stats, total):
    counts = []
    for name, opcode_stat in opcode_stats.items():
        if "execution_count" in opcode_stat:
            count = opcode_stat["execution_count"]
            miss = 0
            if "specializable" not in opcode_stat:
                miss = opcode_stat.get("specialization.miss")
            counts.append((count, name, miss))
    counts.sort(reverse=True)
    cumulative = 0
    rows = []
    for count, name, miss in counts:
        cumulative += count
        if miss:
            miss = format_ratio(miss, count)
        else:
            miss = ""
        rows.append(
            (
                name,
                count,
                format_ratio(count, total),
                format_ratio(cumulative, total),
                miss,
            )
        )
    return rows


def emit_execution_counts(opcode_stats, total):
    with Section("Execution counts", summary="execution counts for all instructions"):
        rows = calculate_execution_counts(opcode_stats, total)
        emit_table(("Name", "Count:", "Self:", "Cumulative:", "Miss ratio:"), rows)


def _emit_comparative_execution_counts(base_rows, head_rows):
    base_data = {x[0]: x[1:] for x in base_rows}
    head_data = {x[0]: x[1:] for x in head_rows}
    opcodes = base_data.keys() | head_data.keys()

    rows = []
    default = [0, "0.0%", "0.0%", 0]
    for opcode in opcodes:
        base_entry = base_data.get(opcode, default)
        head_entry = head_data.get(opcode, default)
        if base_entry[0] == 0:
            change = 1
        else:
            change = (head_entry[0] - base_entry[0]) / base_entry[0]
        rows.append((opcode, base_entry[0], head_entry[0], f"{change:0.1%}"))

    rows.sort(key=lambda x: abs(percentage_to_float(x[-1])), reverse=True)

    emit_table(("Name", "Base Count:", "Head Count:", "Change:"), rows)


def emit_comparative_execution_counts(
    base_opcode_stats, base_total, head_opcode_stats, head_total, level=2
):
    with Section(
        "Execution counts", summary="execution counts for all instructions", level=level
    ):
        base_rows = calculate_execution_counts(base_opcode_stats, base_total)
        head_rows = calculate_execution_counts(head_opcode_stats, head_total)
        _emit_comparative_execution_counts(base_rows, head_rows)


def get_defines():
    spec_path = os.path.join(os.path.dirname(__file__), "../../Python/specialize.c")
    with open(spec_path) as spec_src:
        defines = parse_kinds(spec_src)
    return defines


def emit_specialization_stats(opcode_stats, defines):
    with Section("Specialization stats", summary="specialization stats by family"):
        for name, opcode_stat in opcode_stats.items():
            print_specialization_stats(name, opcode_stat, defines)


def emit_comparative_specialization_stats(
    base_opcode_stats, head_opcode_stats, defines
):
    with Section("Specialization stats", summary="specialization stats by family"):
        opcodes = set(base_opcode_stats.keys()) & set(head_opcode_stats.keys())
        for opcode in opcodes:
            print_comparative_specialization_stats(
                opcode, base_opcode_stats[opcode], head_opcode_stats[opcode], defines
            )


def calculate_specialization_effectiveness(
    opcode_stats, total, specialized_instructions
):
    basic, not_specialized, specialized = categorized_counts(
        opcode_stats, specialized_instructions
    )
    return [
        ("Basic", basic, format_ratio(basic, total)),
        ("Not specialized", not_specialized, format_ratio(not_specialized, total)),
        ("Specialized", specialized, format_ratio(specialized, total)),
    ]


def emit_specialization_overview(opcode_stats, total, specialized_instructions):
    with Section("Specialization effectiveness"):
        rows = calculate_specialization_effectiveness(
            opcode_stats, total, specialized_instructions
        )
        emit_table(("Instructions", "Count:", "Ratio:"), rows)
        for title, field in (
            ("Deferred", "specialization.deferred"),
            ("Misses", "specialization.miss"),
        ):
            total = 0
            counts = []
            for name, opcode_stat in opcode_stats.items():
                # Avoid double counting misses
                if title == "Misses" and "specializable" in opcode_stat:
                    continue
                value = opcode_stat.get(field, 0)
                counts.append((value, name))
                total += value
            counts.sort(reverse=True)
            if total:
                with Section(f"{title} by instruction", 3):
                    rows = [
                        (name, count, format_ratio(count, total))
                        for (count, name) in counts[:10]
                    ]
                    emit_table(("Name", "Count:", "Ratio:"), rows)


def emit_comparative_specialization_overview(
    base_opcode_stats,
    base_total,
    head_opcode_stats,
    head_total,
    specialized_instructions,
):
    with Section("Specialization effectiveness"):
        base_rows = calculate_specialization_effectiveness(
            base_opcode_stats, base_total, specialized_instructions
        )
        head_rows = calculate_specialization_effectiveness(
            head_opcode_stats, head_total, specialized_instructions
        )
        emit_table(
            (
                "Instructions",
                "Base Count:",
                "Base Ratio:",
                "Head Count:",
                "Head Ratio:",
            ),
            join_rows(base_rows, head_rows),
        )


def get_stats_defines():
    stats_path = os.path.join(
        os.path.dirname(__file__), "../../Include/cpython/pystats.h"
    )
    with open(stats_path) as stats_src:
        defines = parse_kinds(stats_src, prefix="EVAL_CALL")
    return defines


def calculate_call_stats(stats, defines):
    total = 0
    for key, value in stats.items():
        if "Calls to" in key:
            total += value
            rows = []
    for key, value in stats.items():
        if "Calls to" in key:
            rows.append((key, value, format_ratio(value, total)))
        elif key.startswith("Calls "):
            name, index = key[:-1].split("[")
            index = int(index)
            label = name + " (" + pretty(defines[index][0]) + ")"
            rows.append((label, value, format_ratio(value, total)))
    for key, value in stats.items():
        if key.startswith("Frame"):
            rows.append((key, value, format_ratio(value, total)))
    return rows


def emit_call_stats(stats, defines):
    with Section("Call stats", summary="Inlined calls and frame stats"):
        rows = calculate_call_stats(stats, defines)
        emit_table(("", "Count:", "Ratio:"), rows)


def emit_comparative_call_stats(base_stats, head_stats, defines):
    with Section("Call stats", summary="Inlined calls and frame stats"):
        base_rows = calculate_call_stats(base_stats, defines)
        head_rows = calculate_call_stats(head_stats, defines)
        rows = join_rows(base_rows, head_rows)
        rows.sort(key=lambda x: -percentage_to_float(x[-1]))
        emit_table(
            ("", "Base Count:", "Base Ratio:", "Head Count:", "Head Ratio:"), rows
        )


def calculate_object_stats(stats):
    total_materializations = stats.get("Object new values")
    total_allocations = stats.get("Object allocations") + stats.get(
        "Object allocations from freelist"
    )
    total_increfs = stats.get("Object interpreter increfs") + stats.get(
        "Object increfs"
    )
    total_decrefs = stats.get("Object interpreter decrefs") + stats.get(
        "Object decrefs"
    )
    rows = []
    for key, value in stats.items():
        if key.startswith("Object"):
            if "materialize" in key:
                ratio = format_ratio(value, total_materializations)
            elif "allocations" in key:
                ratio = format_ratio(value, total_allocations)
            elif "increfs" in key:
                ratio = format_ratio(value, total_increfs)
            elif "decrefs" in key:
                ratio = format_ratio(value, total_decrefs)
            else:
                ratio = ""
            label = key[6:].strip()
            label = label[0].upper() + label[1:]
            rows.append((label, value, ratio))
    return rows


def calculate_gc_stats(stats):
    gc_stats = []
    for key, value in stats.items():
        if not key.startswith("GC"):
            continue
        n, _, rest = key[3:].partition("]")
        name = rest.strip()
        gen_n = int(n)
        while len(gc_stats) <= gen_n:
            gc_stats.append({})
        gc_stats[gen_n][name] = value
    return [
        (i, gen["collections"], gen["objects collected"], gen["object visits"])
        for (i, gen) in enumerate(gc_stats)
    ]


def emit_object_stats(stats):
    with Section("Object stats", summary="allocations, frees and dict materializatons"):
        rows = calculate_object_stats(stats)
        emit_table(("", "Count:", "Ratio:"), rows)


def emit_comparative_object_stats(base_stats, head_stats):
    with Section("Object stats", summary="allocations, frees and dict materializatons"):
        base_rows = calculate_object_stats(base_stats)
        head_rows = calculate_object_stats(head_stats)
        emit_table(
            ("", "Base Count:", "Base Ratio:", "Head Count:", "Head Ratio:"),
            join_rows(base_rows, head_rows),
        )


def emit_gc_stats(stats):
    with Section("GC stats", summary="GC collections and effectiveness"):
        rows = calculate_gc_stats(stats)
        emit_table(
            ("Generation:", "Collections:", "Objects collected:", "Object visits:"),
            rows,
        )


def emit_comparative_gc_stats(base_stats, head_stats):
    with Section("GC stats", summary="GC collections and effectiveness"):
        base_rows = calculate_gc_stats(base_stats)
        head_rows = calculate_gc_stats(head_stats)
        emit_table(
            (
                "Generation:",
                "Base collections:",
                "Head collections:",
                "Base objects collected:",
                "Head objects collected:",
                "Base object visits:",
                "Head object visits:",
            ),
            join_rows(base_rows, head_rows),
        )


def get_total(opcode_stats):
    total = 0
    for opcode_stat in opcode_stats.values():
        if "execution_count" in opcode_stat:
            total += opcode_stat["execution_count"]
    return total


def emit_pair_counts(opcode_stats, total):
    pair_counts = []
    for name_i, opcode_stat in opcode_stats.items():
        for key, value in opcode_stat.items():
            if key.startswith("pair_count"):
                name_j, _, _ = key[11:].partition("]")
                if value:
                    pair_counts.append((value, (name_i, name_j)))
    with Section("Pair counts", summary="Pair counts for top 100 pairs"):
        pair_counts.sort(reverse=True)
        cumulative = 0
        rows = []
        for count, pair in itertools.islice(pair_counts, 100):
            name_i, name_j = pair
            cumulative += count
            rows.append(
                (
                    f"{name_i} {name_j}",
                    count,
                    format_ratio(count, total),
                    format_ratio(cumulative, total),
                )
            )
        emit_table(("Pair", "Count:", "Self:", "Cumulative:"), rows)
    with Section(
        "Predecessor/Successor Pairs",
        summary="Top 5 predecessors and successors of each opcode",
    ):
        predecessors = collections.defaultdict(collections.Counter)
        successors = collections.defaultdict(collections.Counter)
        total_predecessors = collections.Counter()
        total_successors = collections.Counter()
        for count, (first, second) in pair_counts:
            if count:
                predecessors[second][first] = count
                successors[first][second] = count
                total_predecessors[second] += count
                total_successors[first] += count
        for name in opcode_stats.keys():
            total1 = total_predecessors[name]
            total2 = total_successors[name]
            if total1 == 0 and total2 == 0:
                continue
            pred_rows = succ_rows = ()
            if total1:
                pred_rows = [
                    (pred, count, f"{count/total1:.1%}")
                    for (pred, count) in predecessors[name].most_common(5)
                ]
            if total2:
                succ_rows = [
                    (succ, count, f"{count/total2:.1%}")
                    for (succ, count) in successors[name].most_common(5)
                ]
            with Section(name, 3, f"Successors and predecessors for {name}"):
                emit_table(("Predecessors", "Count:", "Percentage:"), pred_rows)
                emit_table(("Successors", "Count:", "Percentage:"), succ_rows)


def calculate_optimization_stats(stats):
    attempts = stats["Optimization attempts"]
    created = stats["Optimization traces created"]
    executed = stats["Optimization traces executed"]
    uops = stats["Optimization uops executed"]
    trace_stack_overflow = stats["Optimization trace stack overflow"]
    trace_stack_underflow = stats["Optimization trace stack underflow"]
    trace_too_long = stats["Optimization trace too long"]
    trace_too_short = stats["Optimiztion trace too short"]
    inner_loop = stats["Optimization inner loop"]
    recursive_call = stats["Optimization recursive call"]

    return [
        ("Optimization attempts", attempts, ""),
        ("Traces created", created, format_ratio(created, attempts)),
        ("Traces executed", executed, ""),
        ("Uops executed", uops, int(uops / (executed or 1))),
        ("Trace stack overflow", trace_stack_overflow, ""),
        ("Trace stack underflow", trace_stack_underflow, ""),
        ("Trace too long", trace_too_long, ""),
        ("Trace too short", trace_too_short, ""),
        ("Inner loop found", inner_loop, ""),
        ("Recursive call", recursive_call, ""),
    ]


def calculate_uop_execution_counts(opcode_stats):
    total = 0
    counts = []
    for name, opcode_stat in opcode_stats.items():
        if "execution_count" in opcode_stat:
            count = opcode_stat["execution_count"]
            counts.append((count, name))
            total += count
    counts.sort(reverse=True)
    cumulative = 0
    rows = []
    for count, name in counts:
        cumulative += count
        rows.append(
            (name, count, format_ratio(count, total), format_ratio(cumulative, total))
        )
    return rows


def emit_optimization_stats(stats):
    if "Optimization attempts" not in stats:
        return

    uop_stats = extract_opcode_stats(stats, "uops")

    with Section(
        "Optimization (Tier 2) stats", summary="statistics about the Tier 2 optimizer"
    ):
        with Section("Overall stats", level=3):
            rows = calculate_optimization_stats(stats)
            emit_table(("", "Count:", "Ratio:"), rows)

        emit_histogram(
            "Trace length histogram",
            stats,
            "Trace length",
            stats["Optimization traces created"],
        )
        emit_histogram(
            "Optimized trace length histogram",
            stats,
            "Optimized trace length",
            stats["Optimization traces created"],
        )
        emit_histogram(
            "Trace run length histogram",
            stats,
            "Trace run length",
            stats["Optimization traces executed"],
        )

        with Section("Uop stats", level=3):
            rows = calculate_uop_execution_counts(uop_stats)
            emit_table(("Uop", "Count:", "Self:", "Cumulative:"), rows)

        with Section("Unsupported opcodes", level=3):
            unsupported_opcodes = extract_opcode_stats(stats, "unsupported_opcode")
            data = []
            for opcode, entry in unsupported_opcodes.items():
                data.append((entry["count"], opcode))
            data.sort(reverse=True)
            rows = [(x[1], x[0]) for x in data]
            emit_table(("Opcode", "Count"), rows)


def emit_comparative_optimization_stats(base_stats, head_stats):
    print("## Comparative optimization stats not implemented\n\n")


def output_single_stats(stats):
    opcode_stats = extract_opcode_stats(stats, "opcode")
    total = get_total(opcode_stats)
    emit_execution_counts(opcode_stats, total)
    emit_pair_counts(opcode_stats, total)
    emit_specialization_stats(opcode_stats, stats["_defines"])
    emit_specialization_overview(
        opcode_stats, total, stats["_specialized_instructions"]
    )
    emit_call_stats(stats, stats["_stats_defines"])
    emit_object_stats(stats)
    emit_gc_stats(stats)
    emit_optimization_stats(stats)
    with Section("Meta stats", summary="Meta statistics"):
        emit_table(("", "Count:"), [("Number of data files", stats["__nfiles__"])])


def output_comparative_stats(base_stats, head_stats):
    base_opcode_stats = extract_opcode_stats(base_stats, "opcode")
    base_total = get_total(base_opcode_stats)

    head_opcode_stats = extract_opcode_stats(head_stats, "opcode")
    head_total = get_total(head_opcode_stats)

    emit_comparative_execution_counts(
        base_opcode_stats, base_total, head_opcode_stats, head_total
    )
    emit_comparative_specialization_stats(
        base_opcode_stats, head_opcode_stats, head_stats["_defines"]
    )
    emit_comparative_specialization_overview(
        base_opcode_stats,
        base_total,
        head_opcode_stats,
        head_total,
        head_stats["_specialized_instructions"],
    )
    emit_comparative_call_stats(base_stats, head_stats, head_stats["_stats_defines"])
    emit_comparative_object_stats(base_stats, head_stats)
    emit_comparative_gc_stats(base_stats, head_stats)
    emit_comparative_optimization_stats(base_stats, head_stats)


def output_stats(inputs, json_output=None):
    if len(inputs) == 1:
        stats = gather_stats(inputs[0])
        if json_output is not None:
            json.dump(stats, json_output)
        output_single_stats(stats)
    elif len(inputs) == 2:
        if json_output is not None:
            raise ValueError("Can not output to JSON when there are multiple inputs")

        base_stats = gather_stats(inputs[0])
        head_stats = gather_stats(inputs[1])
        output_comparative_stats(base_stats, head_stats)

    print("---")
    print("Stats gathered on:", date.today())


def main():
    parser = argparse.ArgumentParser(description="Summarize pystats results")

    parser.add_argument(
        "inputs",
        nargs="*",
        type=str,
        default=[DEFAULT_DIR],
        help=f"""
        Input source(s).
        For each entry, if a .json file, the output provided by --json-output from a previous run;
        if a directory, a directory containing raw pystats .txt files.
        If one source is provided, its stats are printed.
        If two sources are provided, comparative stats are printed.
        Default is {DEFAULT_DIR}.
        """,
    )

    parser.add_argument(
        "--json-output",
        nargs="?",
        type=argparse.FileType("w"),
        help="Output complete raw results to the given JSON file.",
    )

    args = parser.parse_args()

    if len(args.inputs) > 2:
        raise ValueError("0-2 arguments may be provided.")

    output_stats(args.inputs, json_output=args.json_output)


if __name__ == "__main__":
    main()
