#!/usr/bin/env python3
# Copyright 2022 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
"""Collect compilation statistics from benchmark suites.

The benchmark suites need to be built with ninja and enable the CMake option
IREE_ENABLE_LEGACY_COMPILATION_BENCHMARKS.
"""

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 re
import zipfile

from dataclasses import asdict
from typing import BinaryIO, Dict, List, Optional, TextIO

from common.benchmark_definition import CompilationInfo, CompilationResults, CompilationStatistics, ModuleComponentSizes, get_git_commit_hash
from common.benchmark_suite import BenchmarkSuite
from common import benchmark_config
from e2e_test_artifacts import iree_artifacts
from e2e_test_framework import serialization
from e2e_test_framework.definitions import iree_definitions

BENCHMARK_FLAGFILE = "flagfile"
MODULE_DIR = "vmfb"
MODULE_FILE_EXTENSION = "vmfb"
NINJA_LOG_HEADER = "ninja log v5"
NINJA_BUILD_LOG = ".ninja_log"
COMPILATION_STATS_MODULE_SUFFIX = "compile-stats"

VM_COMPONENT_NAME = "module.fb"
CONST_COMPONENT_NAME = "_const.bin"
DISPATCH_COMPONENT_PATTERNS = [
    r".+_embedded_elf_.+\.so",
    r".+_vulkan_spirv_fb\.fb",
    r".+_cuda_nvptx_fb\.fb",
    r".+_vmvx_bytecode_fb\.fb",
]


def match_module_cmake_target(module_path: pathlib.PurePath) -> Optional[str]:
  if module_path.match(f"{benchmark_config.E2E_TEST_ARTIFACTS_REL_PATH}/iree_*/"
                       f"{iree_artifacts.MODULE_FILENAME}"):
    # <e2e test artifacts dir>/iree_<module dir>/<module filename>
    path_parts = module_path.parts[-3:]
  elif module_path.match(
      f"{benchmark_config.BENCHMARK_SUITE_REL_PATH}/*/{MODULE_DIR}/"
      f"*.{MODULE_FILE_EXTENSION}"):
    # <benchmark_suites dir>/<category>/vmfb/<module filename>.vmfb
    path_parts = module_path.parts[-4:]
  else:
    return None
  # Join to get the CMake target name. This is *not* a filesystem path, so we
  # don't want \ separators on Windows that we would get with os.path.join().
  return '/'.join(path_parts)


def parse_compilation_time_from_ninja_log(log: TextIO) -> Dict[str, int]:
  """Retrieve the compilation time (ms) from the Ninja build log.

  Returns:
    Map of target name and compilation time in ms.
  """

  target_build_time_map = {}
  header = log.readline()
  if NINJA_LOG_HEADER not in header:
    raise NotImplementedError(f"Unsupported ninja log version: {header}")

  for line in log:
    start_time, end_time, _, target, _ = line.strip().split("\t")
    cmake_target = match_module_cmake_target(pathlib.PurePath(target))
    if cmake_target is None:
      continue

    start_time = int(start_time)
    end_time = int(end_time)
    target_build_time_map[cmake_target] = end_time - start_time

  return target_build_time_map


def get_module_component_info(module: BinaryIO,
                              module_file_bytes: int) -> ModuleComponentSizes:
  with zipfile.ZipFile(module) as module_zipfile:
    size_map = dict(
        (info.filename, info.file_size) for info in module_zipfile.infolist())

  vm_component_bytes = size_map[VM_COMPONENT_NAME]
  const_component_bytes = size_map[CONST_COMPONENT_NAME]
  identified_names = {VM_COMPONENT_NAME, CONST_COMPONENT_NAME}
  total_dispatch_component_bytes = 0
  for filename, size in size_map.items():
    for pattern in DISPATCH_COMPONENT_PATTERNS:
      if re.match(pattern, filename):
        total_dispatch_component_bytes += size
        identified_names.add(filename)
        break

  if identified_names != set(size_map.keys()):
    raise RuntimeError(
        f"Unrecognized components in the module: {size_map.keys()}.")

  return ModuleComponentSizes(
      file_bytes=module_file_bytes,
      vm_component_bytes=vm_component_bytes,
      const_component_bytes=const_component_bytes,
      total_dispatch_component_bytes=total_dispatch_component_bytes)


def get_module_path(flag_file: TextIO) -> Optional[str]:
  """Retrieve the module path for compilation statistics from the flag file."""

  module_path = None
  for line in flag_file:
    match = re.match("--module=(.+)", line.strip())
    if match:
      module_name, module_ext = os.path.splitext(match.group(1))
      module_path = f"{module_name}-{COMPILATION_STATS_MODULE_SUFFIX}{module_ext}"
      break

  return module_path


def get_module_map_from_compilation_benchmark_config(
    compilation_benchmark_config_data: TextIO,
    e2e_test_artifacts_dir: pathlib.PurePath
) -> Dict[CompilationInfo, pathlib.Path]:
  benchmark_config = json.load(compilation_benchmark_config_data)
  gen_configs = serialization.unpack_and_deserialize(
      data=benchmark_config["generation_configs"],
      root_type=List[iree_definitions.ModuleGenerationConfig])
  module_map = {}
  for gen_config in gen_configs:
    model = gen_config.imported_model.model
    compile_config = gen_config.compile_config
    target_archs = []
    for compile_target in compile_config.compile_targets:
      arch = compile_target.target_architecture
      target_archs.append(
          (f"{arch.type.value}-{arch.architecture}-{arch.microarchitecture}-"
           f"{compile_target.target_abi.value}"))
    compilation_info = CompilationInfo(
        name=gen_config.name,
        model_name=model.name,
        model_tags=tuple(model.tags),
        model_source=model.source_type.value,
        target_arch=f"[{','.join(target_archs)}]",
        compile_tags=tuple(compile_config.tags),
        gen_config_id=gen_config.composite_id)
    module_dir_path = iree_artifacts.get_module_dir_path(
        module_generation_config=gen_config, root_path=e2e_test_artifacts_dir)
    module_path = module_dir_path / iree_artifacts.MODULE_FILENAME
    module_map[compilation_info] = pathlib.Path(module_path)

  return module_map


def get_module_map_from_benchmark_suite(
    benchmark_suite_dir: pathlib.Path) -> Dict[CompilationInfo, pathlib.Path]:
  benchmark_suite = BenchmarkSuite.load_from_benchmark_suite_dir(
      benchmark_suite_dir)
  module_map = {}
  for category, _ in benchmark_suite.list_categories():
    benchmark_cases = benchmark_suite.filter_benchmarks_for_category(
        category=category)
    for benchmark_case in benchmark_cases:
      if benchmark_case.benchmark_case_dir is None:
        raise ValueError("benchmark_case_dir can't be None.")
      benchmark_case_dir = benchmark_case.benchmark_case_dir

      flag_file_path = benchmark_case_dir / BENCHMARK_FLAGFILE
      with flag_file_path.open("r") as flag_file:
        module_path = get_module_path(flag_file)

      if module_path is None:
        raise RuntimeError(
            f"Can't find the module file in the flagfile: {flag_file_path}")
      compilation_info = CompilationInfo.build_with_legacy_name(
          model_name=benchmark_case.model_name,
          model_tags=tuple(benchmark_case.model_tags),
          model_source=category,
          target_arch=benchmark_case.target_arch,
          compile_tags=tuple(benchmark_case.bench_mode))
      module_map[compilation_info] = (benchmark_case_dir /
                                      module_path).resolve()

  return module_map


def _legacy_get_module_map_and_build_log(args: argparse.Namespace):
  module_map = get_module_map_from_benchmark_suite(
      args.build_dir / benchmark_config.BENCHMARK_SUITE_REL_PATH)
  return module_map, args.build_dir / NINJA_BUILD_LOG


def _alpha_get_module_map_and_build_log(args: argparse.Namespace):
  config_data = args.compilation_benchmark_config.open("r")
  module_map = get_module_map_from_compilation_benchmark_config(
      compilation_benchmark_config_data=config_data,
      e2e_test_artifacts_dir=args.e2e_test_artifacts_dir)
  return module_map, args.build_log


def _check_dir_path(path_str: str) -> pathlib.Path:
  path = pathlib.Path(path_str)
  if not path.is_dir():
    raise argparse.ArgumentTypeError(f"{path} is not a directory.")
  return path


def _check_file_path(path_str: str) -> pathlib.Path:
  path = pathlib.Path(path_str)
  if not path.is_file():
    raise argparse.ArgumentTypeError(f"{path} is not a file.")
  return path


def _parse_arguments():
  """Returns an argument parser with common options."""

  # Makes global options come *after* command.
  # See https://stackoverflow.com/q/23296695
  subparser_base = argparse.ArgumentParser(add_help=False)
  subparser_base.add_argument("--output",
                              type=pathlib.Path,
                              help="Path to output JSON file.")
  subparser_base.add_argument(
      "--verbose",
      action="store_true",
      help="Print internal information during execution.")

  parser = argparse.ArgumentParser(
      description="Collect compilation statistics from benchmark suites.")

  subparser = parser.add_subparsers(title="tool version", required=True)
  legacy_parser = subparser.add_parser("legacy",
                                       parents=[subparser_base],
                                       help="Use with legacy benchmark suites.")
  legacy_parser.set_defaults(
      get_module_map_and_build_log=_legacy_get_module_map_and_build_log)
  legacy_parser.add_argument(
      "build_dir",
      type=_check_dir_path,
      help="Path to the build directory containing benchmark suites.")

  alpha_parser = subparser.add_parser("alpha",
                                      parents=[subparser_base],
                                      help="Use with e2e test artifacts.")
  alpha_parser.set_defaults(
      get_module_map_and_build_log=_alpha_get_module_map_and_build_log)
  alpha_parser.add_argument(
      "--compilation_benchmark_config",
      type=_check_file_path,
      required=True,
      help="Exported compilation benchmark config of e2e test artifacts.")
  alpha_parser.add_argument("--build_log",
                            type=_check_file_path,
                            required=True,
                            help="Path to the ninja build log.")
  alpha_parser.add_argument("--e2e_test_artifacts_dir",
                            type=_check_dir_path,
                            required=True,
                            help="Path to the e2e test artifacts directory.")

  return parser.parse_args()


def main(args: argparse.Namespace):
  module_map, build_log_path = args.get_module_map_and_build_log(args)
  with build_log_path.open("r") as log_file:
    target_build_time_map = parse_compilation_time_from_ninja_log(log_file)

  compilation_statistics_list = []
  for compilation_info, module_path in module_map.items():
    with module_path.open("rb") as module_file:
      module_component_sizes = get_module_component_info(
          module_file,
          module_path.stat().st_size)

    cmake_target = match_module_cmake_target(module_path)
    if cmake_target is None:
      raise RuntimeError(
          f"Module path isn't a module cmake target: {module_path}")
    compilation_time_ms = target_build_time_map[cmake_target]
    compilation_statistics = CompilationStatistics(
        compilation_info=compilation_info,
        module_component_sizes=module_component_sizes,
        compilation_time_ms=compilation_time_ms)
    compilation_statistics_list.append(compilation_statistics)

  commit = get_git_commit_hash("HEAD")
  compilation_results = CompilationResults(
      commit=commit, compilation_statistics=compilation_statistics_list)

  json_output = json.dumps(asdict(compilation_results), indent=2)
  if args.output is None:
    print(json_output)
  else:
    args.output.write_text(json_output)


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