#!/usr/bin/env python
# Copyright (c) 2017 The Chromium Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.

"""Script that uploads the specified Skia Gerrit change to Android.

This script does the following:
* Downloads the repo tool.
* Inits and checks out the bare-minimum required Android checkout.
* Sets the required git config options in external/skia.
* Cherry-picks the specified Skia patch.
* Modifies the change subject to append a "Test:" line required for presubmits.
* Uploads the Skia change to Android's Gerrit instance.

After the change is uploaded to Android, developers can trigger TH and download
binaries (if required) after runs complete.

The script re-uses the workdir when it is run again. To start from a clean slate
delete the workdir.

Timings:
* ~1m15s when using an empty/non-existent workdir for the first time.
* ~15s when using a workdir previously populated by the script.

Example usage:
  $ python upload_to_android.py -w /repos/testing -c 44200
"""


from __future__ import print_function
import argparse
import getpass
import json
import os
import subprocess
import stat
import urllib2


REPO_TOOL_URL = 'https://storage.googleapis.com/git-repo-downloads/repo'
SKIA_PATH_IN_ANDROID = os.path.join('external', 'skia')
ANDROID_REPO_URL = 'https://googleplex-android.googlesource.com'
REPO_BRANCH_NAME = 'experiment'
SKIA_GERRIT_INSTANCE = 'https://skia-review.googlesource.com'
SK_USER_CONFIG_PATH = os.path.join('include', 'config', 'SkUserConfig.h')


def get_change_details(change_num):
  response = urllib2.urlopen('%s/changes/%s/detail?o=ALL_REVISIONS' % (
                                 SKIA_GERRIT_INSTANCE, change_num), timeout=5)
  content = response.read()
  # Remove the first line which contains ")]}'\n".
  return json.loads(content[5:])


def init_work_dir(work_dir):
  if not os.path.isdir(work_dir):
    print('Creating %s' % work_dir)
    os.makedirs(work_dir)

  # Ensure the repo tool exists in the work_dir.
  repo_dir = os.path.join(work_dir, 'bin')
  repo_binary = os.path.join(repo_dir, 'repo')
  if not os.path.isdir(repo_dir):
    print('Creating %s' % repo_dir)
    os.makedirs(repo_dir)
  if not os.path.exists(repo_binary):
    print('Downloading %s from %s' % (repo_binary, REPO_TOOL_URL))
    response = urllib2.urlopen(REPO_TOOL_URL, timeout=5)
    content = response.read()
    with open(repo_binary, 'w') as f:
      f.write(content)
    # Set executable bit.
    st = os.stat(repo_binary)
    os.chmod(repo_binary, st.st_mode | stat.S_IEXEC)

  # Create android-repo directory in the work_dir.
  android_dir = os.path.join(work_dir, 'android-repo')
  if not os.path.isdir(android_dir):
    print('Creating %s' % android_dir)
    os.makedirs(android_dir)

  print("""

About to run repo init. If it hangs asking you to run glogin then please:
* Exit the script (ctrl-c).
* Run 'glogin'.
* Re-run the script.

""")
  os.chdir(android_dir)
  subprocess.check_call(
      '%s init -u %s/a/platform/manifest -g "all,-notdefault,-darwin" '
      '-b master --depth=1'
          % (repo_binary, ANDROID_REPO_URL), shell=True)

  print('Syncing the Android checkout at %s' % android_dir)
  subprocess.check_call('%s sync %s tools/repohooks -j 32 -c' % (
                            repo_binary, SKIA_PATH_IN_ANDROID), shell=True)

  # Set the necessary git config options.
  os.chdir(SKIA_PATH_IN_ANDROID)
  subprocess.check_call(
      'git config remote.goog.review %s/' % ANDROID_REPO_URL, shell=True)
  subprocess.check_call(
      'git config review.%s/.autoupload true' % ANDROID_REPO_URL, shell=True)
  subprocess.check_call(
      'git config user.email %s@google.com' % getpass.getuser(), shell=True)

  return repo_binary


class Modifier:
  def modify(self):
    raise NotImplementedError
  def get_user_msg(self):
    raise NotImplementedError


class FetchModifier(Modifier):
  def __init__(self, change_num, debug):
    self.change_num = change_num
    self.debug = debug

  def modify(self):
    # Download and cherry-pick the patch.
    change_details = get_change_details(self.change_num)
    latest_patchset = len(change_details['revisions'])
    mod = int(self.change_num) % 100
    download_ref = 'refs/changes/%s/%s/%s' % (
                       str(mod).zfill(2), self.change_num, latest_patchset)
    subprocess.check_call(
        'git fetch https://skia.googlesource.com/skia %s' % download_ref,
        shell=True)
    subprocess.check_call('git cherry-pick FETCH_HEAD', shell=True)

    if self.debug:
      # Add SK_DEBUG to SkUserConfig.h.
      with open(SK_USER_CONFIG_PATH, 'a') as f:
        f.write('#ifndef SK_DEBUG\n')
        f.write('#define SK_DEBUG\n')
        f.write('#endif//SK_DEBUG\n')
      subprocess.check_call('git add %s' % SK_USER_CONFIG_PATH, shell=True)

    # Amend the commit message to add a prefix that makes it clear that the
    # change should not be submitted and a "Test:" line which is required by
    # Android presubmit checks.
    original_commit_message = change_details['subject']
    new_commit_message = (
        # Intentionally breaking up the below string because some presubmits
        # complain about it.
        '[DO ' + 'NOT ' + 'SUBMIT] %s\n\n'
        'Test: Presubmit checks will test this change.' % (
            original_commit_message))

    subprocess.check_call('git commit --amend -m "%s"' % new_commit_message,
                          shell=True)

  def get_user_msg(self):
    return """

Open the above URL and trigger TH by checking 'Presubmit-Ready'.
You can download binaries (if required) from the TH link after it completes.
"""


# Add a legacy flag if it doesn't exist, or remove it if it exists.
class AndroidLegacyFlagModifier(Modifier):
  def __init__(self, flag):
    self.flag = flag
    self.verb = "Unknown"

  def modify(self):
    flag_line = "  #define %s\n" % self.flag

    config_file = os.path.join('include', 'config', 'SkUserConfigManual.h')

    with open(config_file) as f:
      lines = f.readlines()

    if flag_line not in lines:
      lines.insert(
          lines.index("#endif // SkUserConfigManual_DEFINED\n"), flag_line)
      verb = "Add"
    else:
      lines.remove(flag_line)
      verb = "Remove"

    with open(config_file, 'w') as f:
      for line in lines:
        f.write(line)

    subprocess.check_call('git add %s' % config_file, shell=True)
    message = '%s %s\n\nTest: Presubmit checks will test this change.' % (
        verb, self.flag)

    subprocess.check_call('git commit -m "%s"' % message, shell=True)

  def get_user_msg(self):
      return """

  Please open the above URL to review and land the change.
"""


def upload_to_android(work_dir, modifier):
  repo_binary = init_work_dir(work_dir)

  # Create repo branch.
  subprocess.check_call('%s start %s .' % (repo_binary, REPO_BRANCH_NAME),
                        shell=True)
  try:
    modifier.modify()

    # Upload to Android Gerrit.
    subprocess.check_call('%s upload --verify' % repo_binary, shell=True)

    print(modifier.get_user_msg())
  finally:
    # Abandon repo branch.
    subprocess.call('%s abandon %s' % (repo_binary, REPO_BRANCH_NAME),
                    shell=True)


def main():
  parser = argparse.ArgumentParser()
  parser.add_argument(
      '--work-dir', '-w', required=True,
      help='Directory where an Android checkout will be created (if it does '
           'not already exist). Note: ~1GB space will be used.')
  parser.add_argument(
      '--change-num', '-c', required=True,
      help='The skia-rev Gerrit change number that should be patched into '
           'Android.')
  parser.add_argument(
      '--debug', '-d', action='store_true', default=False,
      help='Adds SK_DEBUG to SkUserConfig.h.')
  args = parser.parse_args()
  upload_to_android(args.work_dir, FetchModifier(args.change_num, args.debug))


if __name__ == '__main__':
  main()
