#!/usr/bin/env python3
# Copyright 2023 The IREE Authors
#
# Licensed under the Apache License v2.0 with LLVM Exceptions.
# See https://llvm.org/LICENSE.txt for license information.
# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
"""Miscellaneous tool to help work with benchmark suite and benchmark CI."""

import pathlib
import sys

# Add build_tools python dir to the search path.
sys.path.insert(0, str(pathlib.Path(__file__).parent.with_name("python")))

import argparse
import json
import os
import shlex
import subprocess
from typing import List, Optional, Sequence

from e2e_test_artifacts import model_artifacts, iree_artifacts
from e2e_test_framework import serialization
from e2e_test_framework.definitions import iree_definitions

IREE_COMPILER_NAME = "iree-compile"


def _convert_to_cmd_string(cmds: Sequence[str]) -> str:
  if os.name == "nt":
    # list2cmdline is an undocumented method for Windows command lines. Python
    # doesn't provide an official method for quoting Windows command lines and
    # the correct implementation is slightly non-trivial. Use the undocumented
    # method for now and can be rewritten with our own implementation later.
    # See https://learn.microsoft.com/en-us/archive/blogs/twistylittlepassagesallalike/everyone-quotes-command-line-arguments-the-wrong-way
    return subprocess.list2cmdline(cmds)

  return " ".join(shlex.quote(cmd) for cmd in cmds)


def _dump_cmds_of_generation_config(
    gen_config: iree_definitions.ModuleGenerationConfig,
    root_path: pathlib.PurePath = pathlib.PurePath()):

  imported_model = gen_config.imported_model
  imported_model_path = iree_artifacts.get_imported_model_path(
      imported_model=imported_model, root_path=root_path)
  module_dir_path = iree_artifacts.get_module_dir_path(
      module_generation_config=gen_config, root_path=root_path)
  module_path = module_dir_path / iree_artifacts.MODULE_FILENAME
  compile_cmds = [
      IREE_COMPILER_NAME,
      str(imported_model_path), "-o",
      str(module_path)
  ]
  compile_cmds += gen_config.materialize_compile_flags(
      module_dir_path=module_dir_path)
  compile_cmd_str = _convert_to_cmd_string(compile_cmds)

  if imported_model.import_config.tool == iree_definitions.ImportTool.NONE:
    import_cmd_str = "# (Source model is already in MLIR)"
  else:
    source_model_path = model_artifacts.get_model_path(
        model=imported_model.model, root_path=root_path)
    import_cmds = [
        imported_model.import_config.tool.value,
        str(source_model_path), "-o",
        str(imported_model_path)
    ]
    import_cmds += imported_model.import_config.materialize_import_flags(
        model=imported_model.model)
    import_cmd_str = _convert_to_cmd_string(import_cmds)

  # Insert a blank line after each command to help read with line wrap.
  return [
      "Compile Module:", compile_cmd_str, "", "Import Model:", import_cmd_str,
      ""
  ]


def _dump_cmds_from_run_config(
    run_config: iree_definitions.E2EModelRunConfig,
    root_path: pathlib.PurePath = pathlib.PurePath()):

  gen_config = run_config.module_generation_config
  module_path = iree_artifacts.get_module_dir_path(
      module_generation_config=gen_config,
      root_path=root_path) / iree_artifacts.MODULE_FILENAME

  run_cmds = [run_config.tool.value, f"--module={module_path}"]
  run_cmds += run_config.materialize_run_flags()
  # Insert a blank line after the command to help read with line wrap.
  lines = ["Run Module:", _convert_to_cmd_string(run_cmds), ""]
  lines += _dump_cmds_of_generation_config(gen_config=gen_config,
                                           root_path=root_path)
  return lines


def _dump_cmds_handler(e2e_test_artifacts_dir: pathlib.Path,
                       execution_benchmark_config: Optional[pathlib.Path],
                       compilation_benchmark_config: Optional[pathlib.Path],
                       benchmark_id: Optional[str], **_unused_args):
  lines = []

  if execution_benchmark_config is not None:
    benchmark_groups = json.loads(execution_benchmark_config.read_text())
    for target_device, benchmark_group in benchmark_groups.items():
      run_configs = serialization.unpack_and_deserialize(
          data=benchmark_group["run_configs"],
          root_type=List[iree_definitions.E2EModelRunConfig])
      for run_config in run_configs:
        if benchmark_id is not None and benchmark_id != run_config.composite_id:
          continue

        lines.append("################")
        lines.append("")
        lines.append(f"Execution Benchmark ID: {run_config.composite_id}")
        lines.append(f"Name: {run_config}")
        lines.append(f"Target Device: {target_device}")
        lines.append("")
        lines += _dump_cmds_from_run_config(run_config=run_config,
                                            root_path=e2e_test_artifacts_dir)

  if compilation_benchmark_config is not None:
    benchmark_config = json.loads(compilation_benchmark_config.read_text())
    gen_configs = serialization.unpack_and_deserialize(
        data=benchmark_config["generation_configs"],
        root_type=List[iree_definitions.ModuleGenerationConfig])
    for gen_config in gen_configs:
      if benchmark_id is not None and benchmark_id != gen_config.composite_id:
        continue

      lines.append("################")
      lines.append("")
      lines.append(f"Compilation Benchmark ID: {gen_config.composite_id}")
      lines.append(f"Name: {gen_config}")
      lines.append("")
      lines += _dump_cmds_of_generation_config(gen_config=gen_config,
                                               root_path=e2e_test_artifacts_dir)

  print(*lines, sep="\n")


def _parse_arguments() -> argparse.Namespace:
  parser = argparse.ArgumentParser(
      description=
      "Miscellaneous tool to help work with benchmark suite and benchmark CI.")

  subparser = parser.add_subparsers(required=True, title="operation")
  dump_cmds_parser = subparser.add_parser(
      "dump-cmds",
      help="Dump the commands to compile and run benchmarks manually.")
  dump_cmds_parser.add_argument(
      "--e2e_test_artifacts_dir",
      type=pathlib.PurePath,
      default=pathlib.Path(),
      help="E2E test artifacts root path used in the outputs of artifact paths")
  dump_cmds_parser.add_argument("--benchmark_id",
                                type=str,
                                help="Only dump the benchmark with this id")
  dump_cmds_parser.add_argument(
      "--execution_benchmark_config",
      type=pathlib.Path,
      help="Config file exported from export_benchmark_config.py execution")
  dump_cmds_parser.add_argument(
      "--compilation_benchmark_config",
      type=pathlib.Path,
      help="Config file exported from export_benchmark_config.py compilation")
  dump_cmds_parser.set_defaults(handler=_dump_cmds_handler)

  args = parser.parse_args()
  if (args.execution_benchmark_config is None and
      args.compilation_benchmark_config is None):
    parser.error("At least one of --execution_benchmark_config or "
                 "--compilation_benchmark_config must be set.")

  return args


def main(args: argparse.Namespace):
  args.handler(**vars(args))


if __name__ == "__main__":
  main(_parse_arguments())
