"""A step to run pre-commit hooks.

See documentation on the precommit recipe - this module
contains the single step in that recipe."""
import logging
import os
import pprint

from helpers import git_utils
from helpers import os_utils
from slave import base_step


class PreCommitStep(base_step.BaseStep):
  """Step for running pre-commit hook checks."""

  def __init__(self, config_file, repo_root_directory, show_output, patch_project: str, commit_counts: int, **kwargs):
    """
    Args:
      config_file: The pre-commit config file to use.
      repo_root_directory: The root directory to the repo checkout.
      show_output: True to make the output a comment on the CL.
      patch_project: The project to check the precommit.
      commit_counts: Number of commits made to the current project.
      **kwargs: Additional args passed to BaseStep.
    """
    base_step.BaseStep.__init__(self, name=f"{patch_project}_precommit", **kwargs)
    self._config_file = config_file
    self._repo_root_directory = repo_root_directory
    self._show_output = show_output
    self._patch_project = patch_project
    self._commit_counts = commit_counts

  def run(self) -> bool:
    """Run the step.

    Returns:
      True if either:
        1. There is a pre-commit config and there were no pre-commit failures.
        2. There was no pre-commit config.
    """
    try:
        directory = self.get_project_path(self._patch_project)
    except KeyError:
        logging.info("Unable to get directory of project %s. Skipping pre-commit.", self._patch_project)
        return True

    pre_commit_config = os.path.join(directory, self._config_file)
    if not os.path.exists(pre_commit_config):
      logging.info("No pre-commit config at %s (%s), skipping",
          pre_commit_config, os.path.abspath(pre_commit_config))
      return True

    results = [self._run_commit_message_hooks(directory, i) for i in range(self._commit_counts)]
    results += [
      self._run_pre_commit_hooks(directory),
      self._run_push_hooks(directory),
    ]
    returncode = max(returncode for returncode, _, _ in results)
    stdout = "\n".join(stdout for _, stdout, _ in results)
    stderr = "\n".join(stderr for _, _, stderr in results)
    if self._show_output:
      try:
        self.add_review({
          "comments": {},
          "message": "stdout: {}\n\nstderr: {}".format(stdout, stderr),
        })
      except UnicodeDecodeError:
        self.add_review({
          "comments": {},
          "message": ("Failed to decode precommit output as unicode, "
            "please check the builder log directly."),
        })
    else:
      self.add_review({
        "comments": {},
        "message": ("This builder is non-blocking and its output can be "
                    "ignored."),
      })
    if returncode:
      return False
    return True

  def _get_env(self):
    env = os.environ.copy()
    env["EUREKAROOT"] = self._repo_root_directory
    logging.info("Using PATH: %s",
      pprint.pformat(env.get("PATH", "").split(":")))
    try:
      chromium_src = self.get_project_path("chromium/src")
      buildtools_path = os.path.join(
        self._repo_root_directory,
        chromium_src,
        "buildtools")
      logging.info("Setting CHROMIUM_BUILDTOOLS_PATH to %s", buildtools_path)
      env["CHROMIUM_BUILDTOOLS_PATH"] = buildtools_path
    except KeyError:
      logging.info("Unable to set CHROMIUM_BUILDTOOLS_PATH, "
        "no chromium/src found.")
    return env

  def _precommit_binary(self) -> str:
    """Get the path to pre-commit in our recipe's virtualenv."""
    return "/workspace/recipe_python_virtual_env/bin/pre-commit"

  def _run_commit_message_hooks(self, directory: str, skips: int) -> tuple[int, str, str]:
    """Run all the hooks for commit message checks.

    Args:
      directory: The directory to execute the command.
      skips: Number of git commit messages to skip.

    Returns:
      A tuple of returncode, stdout, stderr from pre-commit
    """
    env = self._get_env()
    with os_utils.change_cwd(directory):
      commit_message = git_utils.commit_message(self, skip_counts=skips)
      commit_message_path = self.write_temp_file(commit_message)
      logging.debug("Using commit message tempfile %s", commit_message_path)
      cmd = [
        self._precommit_binary(),
        "run",
        "--config", self._config_file,
        "--hook-stage", "commit-msg",
        "--commit-msg-filename", commit_message_path,
      ]
      return self.exec_subprocess(cmd, env=env)

  def _run_pre_commit_hooks(self, directory: str) -> tuple[int, str, str]:
    """Run all the hooks of the 'pre-commit' type.

    This is an unfortunate naming problem - 'pre-commit' the framework
    shares a name with the 'pre-commit' git hook type, which are hooks
    to run before committing. This function runs just those hooks, as
    opposted to pre-push, commit-message, or other hook types.

    Args:
      directory: The directory to execute the command.

    Returns:
      A tuple of returncode, stdout, stderr from pre-commit
    """
    env = self._get_env()
    with os_utils.change_cwd(directory):
      cmd = [
        self._precommit_binary(),
        "run",
        "--config", self._config_file,
        "--source", "HEAD^",
        "--origin", "HEAD"
      ]
      return self.exec_subprocess(cmd, env=env)

  def _run_push_hooks(self, directory: str) -> tuple[int, str, str]:
    """Run all the hooks of the 'push' stage.

    Args:
      directory: The directory to execute the command.

    Returns:
      A tuple of returncode, stdout, stderr from pre-commit
    """
    env = self._get_env()
    with os_utils.change_cwd(directory):
      cmd = [
        self._precommit_binary(),
        "run",
        "--hook-stage", "push",
        "--config", self._config_file,
        "--source", "HEAD^",
        "--origin", "HEAD"
      ]
      return self.exec_subprocess(cmd, env=env)
