#!/usr/bin/env python3
# Copyright 2014 Google Inc.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are
# met:
#
#    * Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
#    * Redistributions in binary form must reproduce the above
# copyright notice, this list of conditions and the following disclaimer
# in the documentation and/or other materials provided with the
# distribution.
#    * Neither the name of Google Inc. nor the names of its
# contributors may be used to endorse or promote products derived from
# this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

"""Parse a DEPS file and git checkout all of the dependencies.
"""

EXTRA_HELP = """
Environment Variables:
  GIT_EXECUTABLE: path to "git" binary; if unset, will look for one of
  ['git', 'git.exe', 'git.bat'] in your default path.

  GIT_SYNC_DEPS_PATH: file to get the dependency list from; if unset,
  will use the file ../DEPS relative to this script's directory.

  GIT_SYNC_DEPS_QUIET: if set to non-empty string, suppress messages.

Git Config:
  To disable syncing of a single repository:
      cd path/to/repository
      git config sync-deps.disable true

  To re-enable sync:
      cd path/to/repository
      git config --unset sync-deps.disable
"""


import argparse
import os
import re
import subprocess
import sys
import threading
from builtins import bytes

def git_executable():
  """Find the git executable.

  Returns:
      A triple:
        A string suitable for passing to subprocess functions, or None.
        The major version number
        The minor version number
  """
  envgit = os.environ.get('GIT_EXECUTABLE')
  searchlist = ['git', 'git.exe', 'git.bat']
  if envgit:
    searchlist.insert(0, envgit)
  with open(os.devnull, 'w') as devnull:
    for git in searchlist:
      major=None
      minor=None
      try:
        version_info = subprocess.check_output([git, '--version']).decode('utf-8')
        match = re.search("^git version (\d+)\.(\d+)",version_info)
        print("Using {}".format(version_info))
        if match:
          major = int(match.group(1))
          minor = int(match.group(2))
        else:
          continue
      except (OSError,):
        continue
      return (git,major,minor)
  return (None,0,0)


DEFAULT_DEPS_PATH = os.path.normpath(
  os.path.join(os.path.dirname(__file__), os.pardir, 'DEPS'))

def get_deps_os_str(deps_file):
  parsed_deps = parse_file_to_dict(deps_file)
  parts = []
  if 'deps_os' in parsed_deps:
    for deps_os in parsed_deps['deps_os']:
      parts.append(' [{}]]'.format(deps_os))
  return "\n".join(parts)

def looks_like_raw_commit(commit):
  return re.match('^[a-f0-9]{40}$', commit) is not None

def git_repository_sync_is_disabled(git, directory):
  try:
    disable = subprocess.check_output(
      [git, 'config', 'sync-deps.disable'], cwd=directory)
    return disable.lower().strip() in ['true', '1', 'yes', 'on']
  except subprocess.CalledProcessError:
    return False


def is_git_toplevel(git, directory):
  """Return true iff the directory is the top level of a Git repository.

  Args:
    git (string) the git executable

    directory (string) the path into which the repository
              is expected to be checked out.
  """
  try:
    toplevel = subprocess.check_output(
      [git, 'rev-parse', '--show-toplevel'], cwd=directory).strip()
    return os.path.realpath(bytes(directory, 'utf8')) == os.path.realpath(toplevel)
  except subprocess.CalledProcessError:
    return False


def status(directory, checkoutable):
  def truncate(s, length):
    return s if len(s) <= length else '...' + s[-(length - 3):]
  dlen = 36
  directory = truncate(directory, dlen)
  checkoutable = truncate(checkoutable, 40)
  sys.stdout.write('%-*s @ %s\n' % (dlen, directory, checkoutable))


def git_checkout_to_directory(git, repo, checkoutable, directory, verbose, treeless):
  """Checkout (and clone if needed) a Git repository.

  Args:
    git (string) the git executable

    repo (string) the location of the repository, suitable
         for passing to `git clone`.

    checkoutable (string) a tag, branch, or commit, suitable for
                 passing to `git checkout`

    directory (string) the path into which the repository
              should be checked out.

    verbose (boolean): emit status info to stdout

    treeless (boolean): when true, clone without any trees.

  Raises an exception if any calls to git fail.
  """
  if not os.path.isdir(directory):
    # Use blobless or treeless checkouts for faster downloads.
    # This defers some work to checkout time.
    # https://github.blog/2020-12-21-get-up-to-speed-with-partial-clone-and-shallow-clone/
    filter = ['--filter=tree:0'] if treeless else ['--filter=blob:none']
    # If the thing to check out looks like a tag (and not like a commit),
    # then limit the checkout to that branch.
    branch = [] if looks_like_raw_commit(checkoutable) else ['--branch={}'.format(checkoutable)]
    subprocess.check_call(
        [git, 'clone', '--quiet', '--single-branch'] + filter + branch + [repo, directory])

  if not is_git_toplevel(git, directory):
    # if the directory exists, but isn't a git repo, you will modify
    # the parent repostory, which isn't what you want.
    sys.stdout.write('%s\n  IS NOT TOP-LEVEL GIT DIRECTORY.\n' % directory)
    return

  # Check to see if this repo is disabled.  Quick return.
  if git_repository_sync_is_disabled(git, directory):
    sys.stdout.write('%s\n  SYNC IS DISABLED.\n' % directory)
    return

  with open(os.devnull, 'w') as devnull:
    # If this fails, we will fetch before trying again.  Don't spam user
    # with error information.
    if 0 == subprocess.call([git, 'checkout', '--quiet', checkoutable],
                            cwd=directory, stderr=devnull):
      # if this succeeds, skip slow `git fetch`.
      if verbose:
        status(directory, checkoutable)  # Success.
      return

  # If the repo has changed, always force use of the correct repo.
  # If origin already points to repo, this is a quick no-op.
  subprocess.check_call(
      [git, 'remote', 'set-url', 'origin', repo], cwd=directory)

  subprocess.check_call([git, 'fetch', '--quiet'], cwd=directory)

  subprocess.check_call([git, 'checkout', '--quiet', checkoutable], cwd=directory)

  if verbose:
    status(directory, checkoutable)  # Success.


def parse_file_to_dict(path):
  dictionary = {}
  contents = open(path).read()
  # Need to convert Var() to vars[], so that the DEPS is actually Python. Var()
  # comes from Autoroller using gclient which has a slightly different DEPS
  # format.
  contents = re.sub(r"Var\((.*?)\)", r"vars[\1]", contents)
  exec(contents, dictionary)
  return dictionary


def git_sync_deps(deps_file_path, command_line_os_requests, verbose, treeless):
  """Grab dependencies, with optional platform support.

  Args:
    deps_file_path (string) Path to the DEPS file.

    command_line_os_requests (list of strings) Can be empty list.
        List of strings that should each be a key in the deps_os
        dictionary in the DEPS file.

    verbose (boolean): emit status info to stdout

    treeless (boolean): when true, clone as treeless instead of blobless

  Raises git Exceptions.
  """
  (git,git_major,git_minor) = git_executable()
  assert git

  # --filter=tree:0 is available in git 2.20 and later
  if (git_major,git_minor) < (2,20):
    print("disabling --treeless: git is older than v2.20")
    treeless = False

  deps_file_directory = os.path.dirname(deps_file_path)
  deps_file = parse_file_to_dict(deps_file_path)
  dependencies = deps_file['deps'].copy()
  os_specific_dependencies = deps_file.get('deps_os', dict())
  if 'all' in command_line_os_requests:
    for value in list(os_specific_dependencies.values()):
      dependencies.update(value)
  else:
    for os_name in command_line_os_requests:
      # Add OS-specific dependencies
      if os_name in os_specific_dependencies:
        dependencies.update(os_specific_dependencies[os_name])
  for directory in dependencies:
    for other_dir in dependencies:
      if directory.startswith(other_dir + '/'):
        raise Exception('%r is parent of %r' % (other_dir, directory))
  list_of_arg_lists = []
  for directory in sorted(dependencies):
    if '@' in dependencies[directory]:
      repo, checkoutable = dependencies[directory].split('@', 1)
    else:
      raise Exception("please specify commit or tag")

    relative_directory = os.path.join(deps_file_directory, directory)

    list_of_arg_lists.append(
      (git, repo, checkoutable, relative_directory, verbose, treeless))

  multithread(git_checkout_to_directory, list_of_arg_lists)

  for directory in deps_file.get('recursedeps', []):
    recursive_path = os.path.join(deps_file_directory, directory, 'DEPS')
    git_sync_deps(recursive_path, command_line_os_requests, verbose)


def multithread(function, list_of_arg_lists):
  # for args in list_of_arg_lists:
  #   function(*args)
  # return
  threads = []
  for args in list_of_arg_lists:
    thread = threading.Thread(None, function, None, args)
    thread.start()
    threads.append(thread)
  for thread in threads:
    thread.join()


def main(argv):
  argparser = argparse.ArgumentParser(
          prog = "git-sync-deps",
          description = "Checkout git-based dependencies as specified by the DEPS file",
          add_help=False # Because we want to print deps_os with -h option
          )
  argparser.add_argument("--help", "-h",
                         action='store_true',
                         help="show this help message and exit")
  argparser.add_argument("--deps",
                         default = os.environ.get('GIT_SYNC_DEPS_PATH', DEFAULT_DEPS_PATH),
                         help="location of the the DEPS file")
  argparser.add_argument("--verbose",
                         default=not bool(os.environ.get('GIT_SYNC_DEPS_QUIET', False)),
                         action='store_true',
                         help="be verbose: print status messages")
  argparser.add_argument("--treeless",
                         default=False,
                         action='store_true',
                         help="""
    Clone repos without trees (--filter=tree:0).
    This is the fastest option for a build machine,
    when you only need a single commit.
    Defers getting objects until checking out a commit.

    The default is to clone with trees but without blobs.

    Only takes effect if using git 2.20 or later.

    See https://github.blog/2020-12-21-get-up-to-speed-with-partial-clone-and-shallow-clone/
                              """)
  argparser.add_argument("os_requests",nargs="*",
                         help="OS requests, as keys in the deps_os dictionariy in the DEPS file")

  args = argparser.parse_args()
  if args.help:
    print(argparser.format_help())
    print(EXTRA_HELP)
    print(get_deps_os_str(args.deps))
    return 0

  git_sync_deps(args.deps, args.os_requests, args.verbose, args.treeless)
  return 0


if __name__ == '__main__':
  exit(main(sys.argv[1:]))
