# 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

import json
import pathlib
import time
from typing import List, Optional, Sequence, Set, Tuple
from common.benchmark_suite import BenchmarkCase, BenchmarkSuite
from common.benchmark_config import BenchmarkConfig
from common.benchmark_definition import (BenchmarkInfo, BenchmarkResults,
                                         BenchmarkMetrics, BenchmarkRun,
                                         DeviceInfo)


class BenchmarkDriver(object):
  """Abstract driver runs the whole benchmark flow."""

  def __init__(self,
               device_info: DeviceInfo,
               benchmark_config: BenchmarkConfig,
               benchmark_suite: BenchmarkSuite,
               benchmark_grace_time: float = 0.0,
               verbose: bool = False):
    self.device_info = device_info
    self.config = benchmark_config
    self.benchmark_suite = benchmark_suite
    self.benchmark_grace_time = benchmark_grace_time
    self.verbose = verbose
    self.finished_benchmarks: List[Tuple[BenchmarkInfo, pathlib.Path]] = []
    self.finished_captures: List[pathlib.Path] = []
    self.benchmark_errors = []
    self._seen_benchmark_names: Set[str] = set()

  def run_benchmark_case(self, benchmark_case: BenchmarkCase,
                         benchmark_results_filename: Optional[pathlib.Path],
                         capture_filename: Optional[pathlib.Path]) -> None:
    """Runs the benchmark case and serializes the results.

    Args:
      benchmark_case: the benchmark_case.
      benchmark_results_filename: the path to store the serialized
        BenchmarkMetrics. Benchmarking is required if set.
      capture_filename: the path to store captured trace. Trace capturing is
        required if set.

    Raises:
      Exception during benchmarking.
    """
    raise NotImplementedError("Should be overwritten by a subclass.")

  def run(self) -> None:
    """Execute the benchmark flow.

    It performs the following steps:
      1. Enumerate and filter benchmark cases.
      2. Call 'run_benchmark_case' for each benchmark case.
      3. Collect the benchmark results and captures.
    """

    self.config.benchmark_results_dir.mkdir(parents=True, exist_ok=True)
    if self.config.trace_capture_config is not None:
      self.config.trace_capture_config.capture_tmp_dir.mkdir(parents=True,
                                                             exist_ok=True)

    cpu_target_arch = self.device_info.get_cpu_arch()
    gpu_target_arch = self.device_info.get_gpu_arch()
    detected_architectures = [
        arch for arch in [cpu_target_arch, gpu_target_arch] if arch is not None
    ]
    if self.config.use_compatible_filter:
      if cpu_target_arch is None:
        print("INFO: Detected unsupported CPU architecture in"
              f' "{self.device_info}", CPU benchmarking is disabled.')
      if gpu_target_arch is None:
        print("INFO: Detected unsupported GPU architecture in"
              f' "{self.device_info}", GPU benchmarking is disabled.')
      compatible_arch_filter = detected_architectures
    else:
      # No compatible filter on the target architectures.
      compatible_arch_filter = None

    drivers, loaders = self.__get_available_drivers_and_loaders()

    benchmark_cases = self.benchmark_suite.filter_benchmarks(
        available_drivers=drivers,
        available_loaders=loaders,
        target_architectures=compatible_arch_filter,
        driver_filter=self.config.driver_filter,
        mode_filter=self.config.mode_filter,
        model_name_filter=self.config.model_name_filter)

    for benchmark_case in benchmark_cases:
      benchmark_info = self.__get_benchmark_info_from_case(
          benchmark_case=benchmark_case)
      benchmark_name = str(benchmark_info)

      if benchmark_case.target_arch not in detected_architectures:
        print(f"WARNING: Benchmark '{benchmark_name}' may be incompatible"
              f" with the detected architectures '{detected_architectures}'"
              f" on the device. Pass --compatible-only to skip incompatible"
              f" benchmarks.")

      # Sanity check for the uniqueness of benchmark names.
      if benchmark_name in self._seen_benchmark_names:
        raise ValueError(
            f"Found duplicate benchmark {benchmark_name} in the suites.")
      self._seen_benchmark_names.add(benchmark_name)

      results_path, capture_path = self.__get_output_paths(benchmark_name)
      # If we continue from the previous results, check and skip if the result
      # files exist.
      if self.config.continue_from_previous:
        if results_path is not None and results_path.exists():
          self.finished_benchmarks.append((benchmark_info, results_path))
          results_path = None

        if capture_path is not None and capture_path.exists():
          self.finished_captures.append(capture_path)
          capture_path = None

      # Skip if no need to benchmark and capture.
      if results_path is None and capture_path is None:
        continue

      print(f"--> Benchmark started: {benchmark_name} <--")

      try:
        self.run_benchmark_case(benchmark_case, results_path, capture_path)
      except Exception as e:
        # Delete unfinished results if they exist.
        if results_path is not None:
          results_path.unlink(missing_ok=True)
        if capture_path is not None:
          capture_path.unlink(missing_ok=True)

        if not self.config.keep_going:
          raise e

        print(f"Processing of benchmark failed with: {e}")
        self.benchmark_errors.append(e)
        continue
      finally:
        # Some grace time.
        time.sleep(self.benchmark_grace_time)

      print("Benchmark completed")

      if results_path:
        self.finished_benchmarks.append((benchmark_info, results_path))
      if capture_path:
        self.finished_captures.append(capture_path)

  def get_benchmark_results(self) -> BenchmarkResults:
    """Returns the finished benchmark results."""

    results = BenchmarkResults()
    results.set_commit(self.config.git_commit_hash)

    finished_benchmarks = sorted(self.finished_benchmarks,
                                 key=lambda pair: str(pair[0]))
    for info, path in finished_benchmarks:
      benchmark_metrics_json_object = json.loads(path.read_text())
      benchmark_run = BenchmarkRun(info=info,
                                   metrics=BenchmarkMetrics.from_json_object(
                                       benchmark_metrics_json_object))
      results.benchmarks.append(benchmark_run)

    return results

  def get_benchmark_result_filenames(self) -> Sequence[pathlib.Path]:
    """Returns the json file paths of finished benchmarks."""
    return [path for info, path in self.finished_benchmarks]

  def get_capture_filenames(self) -> Sequence[pathlib.Path]:
    """Returns the tracy file paths of finished captures."""
    return self.finished_captures

  def get_benchmark_errors(self):
    """Returns the exceptions captured during benchmarking."""
    return self.benchmark_errors

  def __get_output_paths(self, benchmark_name: str):
    """Get output paths for the results and capture. The path of results/capture
    is None if the benchmark/capture doesn't need to be run.
    """

    benchmark_results_filename = None
    if self.config.normal_benchmark_tool_dir:
      benchmark_results_filename = self.config.benchmark_results_dir / f"{benchmark_name}.json"

    capture_filename = None
    if self.config.trace_capture_config:
      capture_filename = self.config.trace_capture_config.capture_tmp_dir / f"{benchmark_name}.tracy"

    return (benchmark_results_filename, capture_filename)

  def __get_benchmark_info_from_case(
      self, benchmark_case: BenchmarkCase) -> BenchmarkInfo:
    run_config = benchmark_case.run_config
    run_tags = run_config.module_execution_config.tags
    gen_config = run_config.module_generation_config
    model_source = str(gen_config.imported_model.model.source_type)
    compile_tags = gen_config.compile_config.tags
    return BenchmarkInfo(name=run_config.name,
                         model_name=benchmark_case.model_name,
                         model_tags=benchmark_case.model_tags,
                         model_source=model_source,
                         bench_mode=run_tags,
                         compile_tags=compile_tags,
                         driver_info=benchmark_case.driver_info,
                         device_info=self.device_info,
                         run_config_id=run_config.composite_id)

  def __get_available_drivers_and_loaders(
      self) -> Tuple[Sequence[str], Sequence[str]]:
    any_tool_dir = (self.config.normal_benchmark_tool_dir
                    if self.config.normal_benchmark_tool_dir else
                    self.config.trace_capture_config.traced_benchmark_tool_dir)
    config_txt_file_path = any_tool_dir / "build_config.txt"
    config_txt_file_lines = config_txt_file_path.read_text().splitlines()

    available_drivers = []
    available_loaders = []
    for line in config_txt_file_lines:
      name, value = line.strip().split("=")
      if value != "ON":
        continue
      if name == "IREE_HAL_DRIVER_CUDA":
        available_drivers.append("cuda")
      elif name == "IREE_HAL_DRIVER_LOCAL_SYNC":
        available_drivers.append("local-sync")
      elif name == "IREE_HAL_DRIVER_LOCAL_TASK":
        available_drivers.append("local-task")
      elif name == "IREE_HAL_DRIVER_VULKAN":
        available_drivers.append("vulkan")
      elif name == "IREE_HAL_EXECUTABLE_LOADER_EMBEDDED_ELF":
        available_loaders.append("embedded-elf")
      elif name == "IREE_HAL_EXECUTABLE_LOADER_SYSTEM_LIBRARY":
        available_loaders.append("system-library")
      elif name == "IREE_HAL_EXECUTABLE_LOADER_VMVX_MODULE":
        available_loaders.append("vmvx-module")
      else:
        continue

    if self.verbose:
      available_drivers_str = ', '.join(available_drivers)
      print(f"Available drivers: {available_drivers_str}")
      available_loaders_str = ', '.join(available_loaders)
      print(f"Available loaders: {available_loaders_str}")

    return available_drivers, available_loaders
