#!/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 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"


def _GetGClientRoot(repo_path):
  """Finds the root of this gclient repo, or returns repo_path if failed."""
  current_path = os.path.normpath(repo_path)
  while not os.access(os.path.join(current_path, ".gclient"), os.R_OK):
    next_path = os.path.dirname(current_path)
    if next_path == current_path:
      return repo_path
    current_path = next_path
  return current_path


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

  def __init__(self, command):
    super(SubprocessFailedException, self).__init__()
    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
  p = subprocess.Popen(popen_args, stdout=subprocess.PIPE, **kwargs)
  output = p.stdout.read().splitlines()
  return p.wait(), output


def main():
  dev_null = open("/dev/null", "w")
  arg_parser = argparse.ArgumentParser(
      description="Syncs to a given Cobalt build id")
  arg_parser.add_argument("buildid", nargs=1)
  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"])
  gclient_root = _GetGClientRoot(os.getcwd())

  for relpath, rep_hash in hashes.iteritems():
    path = os.path.join(gclient_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

  for relpath, rep_hash in hashes.iteritems():
    path = os.path.join(gclient_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)
