#!/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 platform
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
  p = subprocess.Popen(popen_args, stdout=subprocess.PIPE, **kwargs)
  output = p.stdout.read().splitlines()
  return p.wait(), output


def main():
  dev_null_filename = "nul" if platform.system() == "Windows" else "/dev/null"
  dev_null = open(dev_null_filename, "w")
  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.iteritems():
    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] + ".git"
    if remote_url != requested_repo:
      if args.force:
        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.").format(path, requested_repo))
        return 1

  for relpath, rep_hash in hashes.iteritems():
    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)
