#!/usr/bin/python2
"""Syncs to a given Cobalt build id.

Syncs current gclient instance to a given build id, as
generated by "build_id.py" and stored on carbon-airlock-95823.
"""

from __future__ import absolute_import
from __future__ import division
from __future__ import print_function

import argparse
import json
import os
import shutil
import subprocess
import sys
import requests

_BUILD_ID_QUERY_URL = (
    "https://carbon-airlock-95823.appspot.com/build_version/search")
_BUILD_ID_QUERY_PARAMETER_NAME = "build_number"


class SubprocessFailedException(Exception):
  """Exception for non-zero subprocess exits."""

  def __init__(self, command):
    super(SubprocessFailedException, self).__init__()  # pylint: disable=super-with-arguments
    self.command = command

  def __str__(self):
    return "Subprocess failed '{0}'".format(self.command)


def _RunGitCommand(gitargs, **kwargs):
  """Runs a git command with "gitargs", returning the output splitlines().

  Args:
    gitargs: Commandline args that follow 'git'.
    **kwargs: Keyword args for Popen.

  Returns:
    All of stdout, as an array of lines.

  Raises:
    SubprocessFailedException: if the exit code is nonzero.

  """
  result_tuple = _RunGitCommandReturnExitCode(gitargs, **kwargs)
  if result_tuple[0] != 0:
    raise SubprocessFailedException(" ".join(["git"] + gitargs))
  return result_tuple[1]


def _RunGitCommandReturnExitCode(gitargs, **kwargs):
  """Runs a git command with "gitargs", returning the exit code and output.

  Args:
    gitargs: Commandline args that follow 'git'.
    **kwargs: Keyword args for Popen.

  Returns:
    Tuple of (exit code, all of stdout as an array of lines).

  """
  popen_args = ["git"] + gitargs
  with subprocess.Popen(popen_args, stdout=subprocess.PIPE, **kwargs) as p:
    output = p.stdout.read().splitlines()
    return p.wait(), output


def main():
  dev_null = open(os.devnull, "w")  # pylint: disable=consider-using-with
  arg_parser = argparse.ArgumentParser(
      description="Syncs to a given Cobalt build id")
  arg_parser.add_argument("buildid", nargs=1)
  arg_parser.add_argument(
      "--force",
      default=False,
      action="store_true",
      help="Deletes directories that don't match the requested format.")
  args = arg_parser.parse_args()
  r = requests.get(
      _BUILD_ID_QUERY_URL,
      params={_BUILD_ID_QUERY_PARAMETER_NAME: args.buildid[0]})
  if not r.ok:
    print(
        "HTTP request failed\n{0} {1}\n{2}".format(r.status_code, r.reason,
                                                   r.text),
        file=sys.stderr)
    return 1
  # The response starts with a security-related close expression line
  outer_json = json.loads(r.text.splitlines()[1])
  hashes = json.loads(outer_json["deps"])
  git_root = os.getcwd()

  for relpath, rep_hash in hashes.items():
    path = os.path.normpath(os.path.join(git_root, relpath))
    if not os.path.exists(path):
      # No warning in this case, we will attempt to clone the repository in
      # the next pass through the repos.
      continue
    is_dirty = (
        bool(
            _RunGitCommandReturnExitCode(["diff", "--no-ext-diff", "--quiet"],
                                         cwd=path,
                                         stderr=dev_null)[0]) or
        bool(
            _RunGitCommandReturnExitCode(
                ["diff", "--no-ext-diff", "--quiet", "--cached"],
                cwd=path,
                stderr=dev_null)[0]))

    if is_dirty:
      print("{0} is dirty, please resolve".format(relpath))
      return 1

    (requested_repo, _) = rep_hash.split("@")
    remote_url = _RunGitCommand(["config", "--get", "remote.origin.url"],
                                cwd=path)[0].strip().decode("utf-8")
    if requested_repo.endswith(".git"):
      if remote_url + ".git" == requested_repo:
        print(("WARNING: You are syncing to {0} instead of {1}. While these "
               "point to the same repo, the differing extension will cause "
               "different build ids to be generated. If you need the same "
               "id, you'll need to specifically clone {0} (note the .git "
               "extension).").format(requested_repo, remote_url))
        remote_url += ".git"

    if remote_url != requested_repo:
      if args.force and path != git_root:
        shutil.rmtree(path)
      else:
        print(("{0} exists but does not point to the requested repo for that "
               "path, {1}. Either replace that directory manually or run this "
               "script with --force. --force will not try to remove the top "
               "level repository.").format(path, requested_repo))
        return 1

  for relpath, rep_hash in hashes.items():
    path = os.path.normpath(os.path.join(git_root, relpath))

    # repo_hash has a repo path prefix like this:
    # 'https://chromium.googlesource.com/chromium/llvm-project/libcxx.git
    # @48198f9110397fff47fe7c37cbfa296be7d44d3d'
    (requested_repo, requested_hash) = rep_hash.split("@")

    if not os.path.exists(path):
      print("Missing path {0}, cloning from {1}.".format(path, requested_repo))
      try:
        # The clone command will create all missing directories leading to the
        # path.  If the clone is successful, we continue on as usual and let
        # the subsequent logic here checkout the appropriate git hash.
        _RunGitCommand(["clone", "-q", requested_repo, path])
      except SubprocessFailedException:
        print("There was an error cloning the repository.")
        continue

    current_hash = _RunGitCommand(["rev-parse", "HEAD"], cwd=path)[0]

    if requested_hash == current_hash:
      continue
    symbolic_ref = None
    try:
      symbolic_ref = _RunGitCommand(["symbolic-ref", "--short", "-q", "HEAD"],
                                    cwd=path,
                                    stderr=dev_null)[0]
    except SubprocessFailedException:
      pass

    user_visible_commit = symbolic_ref if symbolic_ref else current_hash[0:7]

    print("{0} was at {1} now {2}".format(path, user_visible_commit,
                                          requested_hash[0:7]))

    _RunGitCommand(["checkout", "-q", "--detach", requested_hash], cwd=path)

  return 0


if __name__ == "__main__":
  try:
    sys.exit(main())
  except SubprocessFailedException as ex:
    print(str(ex), file=sys.stderr)
    sys.exit(1)
