#!/usr/bin/env python
#
# Copyright 2019 Google Inc.
#
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.


from __future__ import print_function
import os
import re
import subprocess
import sys

from infra import git
from infra import go

_TOOLS_DIR = os.path.dirname(os.path.abspath(__file__))
_REPO_ROOT = os.path.realpath(os.path.join(_TOOLS_DIR, os.pardir))
_INFRA_BOTS = os.path.join(_REPO_ROOT, 'infra', 'bots')
sys.path.insert(0, _INFRA_BOTS)
import git_utils


REFS_HEADS_PREFIX = 'refs/heads/'
CHROME_REF_PREFIX = REFS_HEADS_PREFIX + 'chrome/m'
SK_MILESTONE_H = os.path.join('include', 'core', 'SkMilestone.h')
SK_MILESTONE_TMPL = r'#define SK_MILESTONE %s'
SK_MILESTONE_RE = SK_MILESTONE_TMPL % r'(\d+)'
SKIA_REPO = 'https://skia.googlesource.com/skia.git'
SUPPORTED_CHROME_BRANCHES = 3
UPDATE_MILESTONE_COMMIT_MSG = '''Update Skia milestone to %d'''


def get_current_milestone():
  '''Read SkMilestone.h and parse out the current milestone.'''
  sk_milestone = os.path.join(_REPO_ROOT, SK_MILESTONE_H)
  with open(sk_milestone, 'r') as f:
    contents = f.read()
  for line in contents.splitlines():
    m = re.match(SK_MILESTONE_RE, line)
    if m:
      return int(m.groups()[0])
  print >> sys.stderr, (
      'Failed to parse %s; has the format changed?' % SK_MILESTONE_H)
  sys.exit(1)


def create_new_branch(new_branch, branch_at):
  '''Create a temporary checkout of the repo, create the new branch and push.'''
  b = new_branch[len(REFS_HEADS_PREFIX):]
  with git_utils.NewGitCheckout(SKIA_REPO, local=_REPO_ROOT):
    git.git('checkout', '-b', b)
    git.git('reset', '--hard', branch_at)
    git.git('push', '--set-upstream', 'origin', b)


def update_milestone(m):
  '''Update SkMilestone.h to match the given milestone number.'''
  with git_utils.NewGitCheckout(SKIA_REPO, local=_REPO_ROOT):
    with git_utils.GitBranch(
        'update_milestone', UPDATE_MILESTONE_COMMIT_MSG % m):
      with open(SK_MILESTONE_H, 'r+') as f:
        contents = re.sub(
            SK_MILESTONE_RE, SK_MILESTONE_TMPL % str(m), f.read(), flags=re.M)
        f.seek(0)
        f.write(contents)
        f.truncate()
      git.git('diff')


def update_infra_config(old_branch, new_branch):
  '''Create a CL to add infra support for the new branch and remove the old.'''
  owner = git.git('config', 'user.email').rstrip()
  if not owner:
    print >> sys.stderr, ('No configured git user; please run '
                          '"git config user.email <your email>".')
    sys.exit(1)
  go.mod_download()
  go.install(go.INFRA_GO+'/go/supported_branches/cmd/new-branch')
  subprocess.check_call(['new-branch',
                         '--branch', new_branch[len(REFS_HEADS_PREFIX):],
                         '--delete', old_branch[len(REFS_HEADS_PREFIX):],
                         '--owner', owner,
                         '--exclude-trybots=chromium.*',
                         '--exclude-trybots=.*Android_Framework.*',
                         '--exclude-trybots=.*G3_Framework.*',
                         '--exclude-trybots=.*CanvasKit.*',
                         '--exclude-trybots=.*PathKit.*',
                         '--submit'])


def main():
  if len(sys.argv) != 2 or '--help' in sys.argv or '-h' in sys.argv:
    print >> sys.stderr, 'Usage: %s <commit hash for branch>' % sys.argv[0]
    sys.exit(1)
  go.check()
  branch_at = sys.argv[1]
  m = get_current_milestone()
  new_branch = '%s%d' % (CHROME_REF_PREFIX, m)
  old_branch = '%s%d' % (CHROME_REF_PREFIX, m-SUPPORTED_CHROME_BRANCHES)
  print('Creating branch %s and removing support (eg. CQ) for %s' % (
      new_branch, old_branch))
  create_new_branch(new_branch, branch_at)
  update_milestone(m+1)
  update_infra_config(old_branch, new_branch)


if __name__ == '__main__':
  main()
