#!/usr/bin/env python3
import argparse
import subprocess
from typing import *
import tempfile
import copy
import os
import shutil
import sys
import re
import configparser
from types import SimpleNamespace
from textwrap import dedent

# USAGE:
# 0. Prepare two BOLT build versions: base and compare.
# 1. Create the config by invoking this script with required options.
#    Save the config as `llvm-bolt-wrapper.ini` next to the script or
#    in the testing directory.
# In the base BOLT build directory:
# 2. Rename `llvm-bolt` to `llvm-bolt.real`
# 3. Create a symlink from this script to `llvm-bolt`
# 4. Create `llvm-bolt-wrapper.ini` and fill it using the example below.
#
# This script will compare binaries produced by base and compare BOLT, and
# report elapsed processing time and max RSS.

# read options from config file llvm-bolt-wrapper.ini in script CWD
#
# [config]
# # mandatory
# base_bolt = /full/path/to/llvm-bolt.real
# cmp_bolt = /full/path/to/other/llvm-bolt
# # optional, default to False
# verbose
# keep_tmp
# no_minimize
# run_sequentially
# compare_output
# skip_binary_cmp
# # optional, defaults to timing.log in CWD
# timing_file = timing1.log


def read_cfg():
    src_dir = os.path.dirname(os.path.abspath(__file__))
    cfg = configparser.ConfigParser(allow_no_value=True)
    cfgs = cfg.read("llvm-bolt-wrapper.ini")
    if not cfgs:
        cfgs = cfg.read(os.path.join(src_dir, "llvm-bolt-wrapper.ini"))
    assert cfgs, f"llvm-bolt-wrapper.ini is not found in {os.getcwd()}"

    def get_cfg(key):
        # if key is not present in config, assume False
        if key not in cfg["config"]:
            return False
        # if key is present, but has no value, assume True
        if not cfg["config"][key]:
            return True
        # if key has associated value, interpret the value
        return cfg["config"].getboolean(key)

    d = {
        # BOLT binary locations
        "BASE_BOLT": cfg["config"]["base_bolt"],
        "CMP_BOLT": cfg["config"]["cmp_bolt"],
        # optional
        "VERBOSE": get_cfg("verbose"),
        "KEEP_TMP": get_cfg("keep_tmp"),
        "NO_MINIMIZE": get_cfg("no_minimize"),
        "RUN_SEQUENTIALLY": get_cfg("run_sequentially"),
        "COMPARE_OUTPUT": get_cfg("compare_output"),
        "SKIP_BINARY_CMP": get_cfg("skip_binary_cmp"),
        "TIMING_FILE": cfg["config"].get("timing_file", "timing.log"),
    }
    if d["VERBOSE"]:
        print(f"Using config {os.path.abspath(cfgs[0])}")
    return SimpleNamespace(**d)


# perf2bolt mode
PERF2BOLT_MODE = ["-aggregate-only", "-ignore-build-id"]

# boltdiff mode
BOLTDIFF_MODE = ["-diff-only", "-o", "/dev/null"]

# options to suppress binary differences as much as possible
MINIMIZE_DIFFS = ["-bolt-info=0"]

# bolt output options that need to be intercepted
BOLT_OUTPUT_OPTS = {
    "-o": "BOLT output binary",
    "-w": "BOLT recorded profile",
}

# regex patterns to exclude the line from log comparison
SKIP_MATCH = [
    "BOLT-INFO: BOLT version",
    r"^Args: ",
    r"^BOLT-DEBUG:",
    r"BOLT-INFO:.*data.*output data",
    "WARNING: reading perf data directly",
]


def run_cmd(cmd, out_f, cfg):
    if cfg.VERBOSE:
        print(" ".join(cmd))
    return subprocess.Popen(cmd, stdout=out_f, stderr=subprocess.STDOUT)


def run_bolt(bolt_path, bolt_args, out_f, cfg):
    p2b = os.path.basename(sys.argv[0]) == "perf2bolt"  # perf2bolt mode
    bd = os.path.basename(sys.argv[0]) == "llvm-boltdiff"  # boltdiff mode
    cmd = ["/usr/bin/time", "-f", "%e %M", bolt_path] + bolt_args
    if p2b:
        # -ignore-build-id can occur at most once, hence remove it from cmd
        if "-ignore-build-id" in cmd:
            cmd.remove("-ignore-build-id")
        cmd += PERF2BOLT_MODE
    elif bd:
        cmd += BOLTDIFF_MODE
    elif not cfg.NO_MINIMIZE:
        cmd += MINIMIZE_DIFFS
    return run_cmd(cmd, out_f, cfg)


def prepend_dash(args: Mapping[AnyStr, AnyStr]) -> Sequence[AnyStr]:
    """
    Accepts parsed arguments and returns flat list with dash prepended to
    the option.
    Example: Namespace(o='test.tmp') -> ['-o', 'test.tmp']
    """
    dashed = [("-" + key, value) for (key, value) in args.items()]
    flattened = list(sum(dashed, ()))
    return flattened


def replace_cmp_path(tmp: AnyStr, args: Mapping[AnyStr, AnyStr]) -> Sequence[AnyStr]:
    """
    Keeps file names, but replaces the path to a temp folder.
    Example: Namespace(o='abc/test.tmp') -> Namespace(o='/tmp/tmpf9un/test.tmp')
    Except preserve /dev/null.
    """
    replace_path = (
        lambda x: os.path.join(tmp, os.path.basename(x))
        if x != "/dev/null"
        else "/dev/null"
    )
    new_args = {key: replace_path(value) for key, value in args.items()}
    return prepend_dash(new_args)


def preprocess_args(args: argparse.Namespace) -> Mapping[AnyStr, AnyStr]:
    """
    Drop options that weren't parsed (e.g. -w), convert to a dict
    """
    return {key: value for key, value in vars(args).items() if value}


def write_to(txt, filename, mode="w"):
    with open(filename, mode) as f:
        f.write(txt)


def wait(proc, fdesc):
    proc.wait()
    fdesc.close()
    return open(fdesc.name)


def compare_logs(main, cmp, skip_begin=0, skip_end=0, str_input=True):
    """
    Compares logs but allows for certain lines to be excluded from comparison.
    If str_input is True (default), the input it assumed to be a string,
    which is split into lines. Otherwise the input is assumed to be a file.
    Returns None on success, mismatch otherwise.
    """
    main_inp = main.splitlines() if str_input else main.readlines()
    cmp_inp = cmp.splitlines() if str_input else cmp.readlines()
    # rewind logs after consumption
    if not str_input:
        main.seek(0)
        cmp.seek(0)
    for lhs, rhs in list(zip(main_inp, cmp_inp))[skip_begin : -skip_end or None]:
        if lhs != rhs:
            # check skip patterns
            for skip in SKIP_MATCH:
                # both lines must contain the pattern
                if re.search(skip, lhs) and re.search(skip, rhs):
                    break
            # otherwise return mismatching lines
            else:
                return (lhs, rhs)
    return None


def fmt_cmp(cmp_tuple):
    if not cmp_tuple:
        return ""
    return f"main:\n{cmp_tuple[0]}\ncmp:\n{cmp_tuple[1]}\n"


def compare_with(lhs, rhs, cmd, skip_begin=0, skip_end=0):
    """
    Runs cmd on both lhs and rhs and compares stdout.
    Returns tuple (mismatch, lhs_stdout):
        - if stdout matches between two files, mismatch is None,
        - otherwise mismatch is a tuple of mismatching lines.
    """
    run = lambda binary: subprocess.run(
        cmd.split() + [binary], text=True, check=True, capture_output=True
    ).stdout
    run_lhs = run(lhs)
    run_rhs = run(rhs)
    cmp = compare_logs(run_lhs, run_rhs, skip_begin, skip_end)
    return cmp, run_lhs


def parse_cmp_offset(cmp_out):
    """
    Extracts byte number from cmp output:
    file1 file2 differ: byte X, line Y
    """
    # NOTE: cmp counts bytes starting from 1!
    return int(re.search(r"byte (\d+),", cmp_out).groups()[0]) - 1


def report_real_time(binary, main_err, cmp_err, cfg):
    """
    Extracts real time from stderr and appends it to TIMING FILE it as csv:
    "output binary; base bolt; cmp bolt"
    """

    def get_real_from_stderr(logline):
        return "; ".join(logline.split())

    for line in main_err:
        pass
    main = get_real_from_stderr(line)
    for line in cmp_err:
        pass
    cmp = get_real_from_stderr(line)
    write_to(f"{binary}; {main}; {cmp}\n", cfg.TIMING_FILE, "a")
    # rewind logs after consumption
    main_err.seek(0)
    cmp_err.seek(0)


def clean_exit(tmp, out, exitcode, cfg):
    # temp files are only cleaned on success
    if not cfg.KEEP_TMP:
        shutil.rmtree(tmp)

    # report stdout and stderr from the main process
    shutil.copyfileobj(out, sys.stdout)
    sys.exit(exitcode)


def find_section(offset, readelf_hdr):
    hdr = readelf_hdr.split("\n")
    section = None
    # extract sections table (parse objdump -hw output)
    for line in hdr[5:-1]:
        cols = line.strip().split()
        # extract section offset
        file_offset = int(cols[5], 16)
        # section size
        size = int(cols[2], 16)
        if offset >= file_offset and offset < file_offset + size:
            if sys.stdout.isatty():  # terminal supports colors
                print(f"\033[1m{line}\033[0m")
            else:
                print(f">{line}")
            section = cols[1]
        else:
            print(line)
    return section


def main_config_generator():
    parser = argparse.ArgumentParser()
    parser.add_argument("base_bolt", help="Full path to base llvm-bolt binary")
    parser.add_argument("cmp_bolt", help="Full path to cmp llvm-bolt binary")
    parser.add_argument(
        "--verbose",
        action="store_true",
        help="Print subprocess invocation cmdline (default False)",
    )
    parser.add_argument(
        "--keep_tmp",
        action="store_true",
        help="Preserve tmp folder on a clean exit "
        "(tmp directory is preserved on crash by default)",
    )
    parser.add_argument(
        "--no_minimize",
        action="store_true",
        help=f"Do not add `{MINIMIZE_DIFFS}` that is used "
        "by default to reduce binary differences",
    )
    parser.add_argument(
        "--run_sequentially",
        action="store_true",
        help="Run both binaries sequentially (default "
        "in parallel). Use for timing comparison",
    )
    parser.add_argument(
        "--compare_output",
        action="store_true",
        help="Compare bolt stdout/stderr (disabled by default)",
    )
    parser.add_argument(
        "--skip_binary_cmp", action="store_true", help="Disable output comparison"
    )
    parser.add_argument(
        "--timing_file",
        help="Override path to timing log " "file (default `timing.log` in CWD)",
    )
    args = parser.parse_args()

    print(
        dedent(
            f"""\
    [config]
    # mandatory
    base_bolt = {args.base_bolt}
    cmp_bolt = {args.cmp_bolt}"""
        )
    )
    del args.base_bolt
    del args.cmp_bolt
    d = vars(args)
    if any(d.values()):
        print("# optional")
        for key, value in d.items():
            if value:
                print(key)


def main():
    cfg = read_cfg()
    # intercept output arguments
    parser = argparse.ArgumentParser(add_help=False)
    for option, help in BOLT_OUTPUT_OPTS.items():
        parser.add_argument(option, help=help)
    args, unknownargs = parser.parse_known_args()
    args = preprocess_args(args)
    cmp_args = copy.deepcopy(args)
    tmp = tempfile.mkdtemp()
    cmp_args = replace_cmp_path(tmp, cmp_args)

    # reconstruct output arguments: prepend dash
    args = prepend_dash(args)

    # run both BOLT binaries
    main_f = open(os.path.join(tmp, "main_bolt.stdout"), "w")
    cmp_f = open(os.path.join(tmp, "cmp_bolt.stdout"), "w")
    main_bolt = run_bolt(cfg.BASE_BOLT, unknownargs + args, main_f, cfg)
    if cfg.RUN_SEQUENTIALLY:
        main_out = wait(main_bolt, main_f)
        cmp_bolt = run_bolt(cfg.CMP_BOLT, unknownargs + cmp_args, cmp_f, cfg)
    else:
        cmp_bolt = run_bolt(cfg.CMP_BOLT, unknownargs + cmp_args, cmp_f, cfg)
        main_out = wait(main_bolt, main_f)
    cmp_out = wait(cmp_bolt, cmp_f)

    # check exit code
    if main_bolt.returncode != cmp_bolt.returncode:
        print(tmp)
        exit("exitcode mismatch")

    # don't compare output upon unsuccessful exit
    if main_bolt.returncode != 0:
        cfg.SKIP_BINARY_CMP = True

    # compare logs, skip_end=1 skips the line with time
    out = (
        compare_logs(main_out, cmp_out, skip_end=1, str_input=False)
        if cfg.COMPARE_OUTPUT
        else None
    )
    if out:
        print(tmp)
        print(fmt_cmp(out))
        write_to(fmt_cmp(out), os.path.join(tmp, "summary.txt"))
        exit("logs mismatch")

    if os.path.basename(sys.argv[0]) == "llvm-boltdiff":  # boltdiff mode
        # no output binary to compare, so just exit
        clean_exit(tmp, main_out, main_bolt.returncode, cfg)

    # compare binaries (using cmp)
    main_binary = args[args.index("-o") + 1]
    cmp_binary = cmp_args[cmp_args.index("-o") + 1]
    if main_binary == "/dev/null":
        assert cmp_binary == "/dev/null"
        cfg.SKIP_BINARY_CMP = True

    # report binary timing as csv: output binary; base bolt real; cmp bolt real
    report_real_time(main_binary, main_out, cmp_out, cfg)

    if not cfg.SKIP_BINARY_CMP:
        # check if files exist
        main_exists = os.path.exists(main_binary)
        cmp_exists = os.path.exists(cmp_binary)
        if main_exists and cmp_exists:
            # proceed to comparison
            pass
        elif not main_exists and not cmp_exists:
            # both don't exist, assume it's intended, skip comparison
            clean_exit(tmp, main_out, main_bolt.returncode, cfg)
        elif main_exists:
            assert not cmp_exists
            exit(f"{cmp_binary} doesn't exist")
        else:
            assert not main_exists
            exit(f"{main_binary} doesn't exist")

        cmp_proc = subprocess.run(
            ["cmp", "-b", main_binary, cmp_binary], capture_output=True, text=True
        )
        if cmp_proc.returncode:
            # check if output is an ELF file (magic bytes)
            with open(main_binary, "rb") as f:
                magic = f.read(4)
                if magic != b"\x7fELF":
                    exit("output mismatch")
            # check if ELF headers match
            mismatch, _ = compare_with(main_binary, cmp_binary, "readelf -We")
            if mismatch:
                print(fmt_cmp(mismatch))
                write_to(fmt_cmp(mismatch), os.path.join(tmp, "headers.txt"))
                exit("headers mismatch")
            # if headers match, compare sections (skip line with filename)
            mismatch, hdr = compare_with(
                main_binary, cmp_binary, "objdump -hw", skip_begin=2
            )
            assert not mismatch
            # check which section has the first mismatch
            mismatch_offset = parse_cmp_offset(cmp_proc.stdout)
            section = find_section(mismatch_offset, hdr)
            exit(f"binary mismatch @{hex(mismatch_offset)} ({section})")

    clean_exit(tmp, main_out, main_bolt.returncode, cfg)


if __name__ == "__main__":
    # config generator mode if the script is launched as is
    if os.path.basename(__file__) == "llvm-bolt-wrapper.py":
        main_config_generator()
    else:
        # llvm-bolt interceptor mode otherwise
        main()
