#!/usr/bin/python
#
# Copyright (C) 2012 The Android Open Source Project
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#      http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

"""Merge Chromium into the Android tree."""

import contextlib
import logging
import optparse
import os
import re
import sys
import urllib2

import merge_common


# We need to import this *after* merging from upstream to get the latest
# version. Set it to none here to catch uses before it's imported.
webview_licenses = None


AUTOGEN_MESSAGE = 'This commit was generated by merge_from_chromium.py.'
SRC_GIT_BRANCH = 'refs/remotes/history/upstream-master'


def _ReadGitFile(sha1, path, git_url=None, git_branch=None):
  """Reads a file from a (possibly remote) git project at a specific revision.

  Args:
    sha1: The SHA1 at which to read.
    path: The relative path of the file to read.
    git_url: The URL of the git server, if reading a remote project.
    git_branch: The branch to fetch, if reading a remote project.
  Returns:
    The contents of the specified file.
  """
  if git_url:
    merge_common.GetCommandStdout(['git', 'fetch', '-f', git_url, git_branch])
  return merge_common.GetCommandStdout(['git', 'show', '%s:%s' % (sha1, path)])


def _ParseDEPS(deps_content):
  """Parses the .DEPS.git file from Chromium and returns its contents.

  Args:
    deps_content: The contents of the .DEPS.git file as text.
  Returns:
    A dictionary of the contents of .DEPS.git at the specified revision
  """

  class FromImpl(object):
    """Used to implement the From syntax."""

    def __init__(self, module_name):
      self.module_name = module_name

    def __str__(self):
      return 'From("%s")' % self.module_name

  class _VarImpl(object):
    def __init__(self, custom_vars, local_scope):
      self._custom_vars = custom_vars
      self._local_scope = local_scope

    def Lookup(self, var_name):
      """Implements the Var syntax."""
      if var_name in self._custom_vars:
        return self._custom_vars[var_name]
      elif var_name in self._local_scope.get('vars', {}):
        return self._local_scope['vars'][var_name]
      raise Exception('Var is not defined: %s' % var_name)

  tmp_locals = {}
  var = _VarImpl({}, tmp_locals)
  tmp_globals = {'From': FromImpl, 'Var': var.Lookup, 'deps_os': {}}
  exec(deps_content) in tmp_globals, tmp_locals
  return tmp_locals


def _GetProjectMergeInfo(projects, deps_vars):
  """Gets the git URL and SHA1 for each project based on .DEPS.git.

  Args:
    projects: The list of projects to consider.
    deps_vars: The dictionary of dependencies from .DEPS.git.
  Returns:
    A dictionary from project to git URL and SHA1 - 'path: (url, sha1)'
  Raises:
    TemporaryMergeError: if a project to be merged is not found in .DEPS.git.
  """
  deps_fallback_order = [
      deps_vars['deps'],
      deps_vars['deps_os']['unix'],
      deps_vars['deps_os']['android'],
  ]
  result = {}
  for path in projects:
    for deps in deps_fallback_order:
      if len(path) > 0:
        upstream_path = os.path.join('src', path)
      else:
        upstream_path = 'src'
      url_plus_sha1 = deps.get(upstream_path)
      if url_plus_sha1:
        break
    else:
      raise merge_common.TemporaryMergeError(
          'Could not find .DEPS.git entry for project %s. This probably '
          'means that the project list in merge_from_chromium.py needs to be '
          'updated.' % path)
    match = re.match('(.*?)@(.*)', url_plus_sha1)
    url = match.group(1)
    sha1 = match.group(2)
    logging.debug('  Got URL %s and SHA1 %s for project %s', url, sha1, path)
    result[path] = {'url': url, 'sha1': sha1}
  return result


def _MergeProjects(version, root_sha1, target, unattended, buildspec_url):
  """Merges each required Chromium project into the Android repository.

  .DEPS.git is consulted to determine which revision each project must be merged
  at. Only a whitelist of required projects are merged.

  Args:
    version: The version to mention in generated commit messages.
    root_sha1: The git hash to merge in the root repository.
    target: The target branch to merge to.
    unattended: Run in unattended mode.
    buildspec_url: URL for buildspec repository, when merging a branch.
  Raises:
    TemporaryMergeError: If incompatibly licensed code is left after pruning.
  """
  # The logic for this step lives here, in the Android tree, as it makes no
  # sense for a Chromium tree to know about this merge.

  if unattended:
    branch_create_flag = '-B'
  else:
    branch_create_flag = '-b'
  branch_name = 'merge-from-chromium-%s' % version

  logging.debug('Parsing DEPS ...')
  if root_sha1:
    deps_content = _ReadGitFile(root_sha1, '.DEPS.git')
  else:
    deps_content = _ReadGitFile('FETCH_HEAD', version + '/DEPS',
                                buildspec_url, 'master')

  deps_vars = _ParseDEPS(deps_content)

  merge_info = _GetProjectMergeInfo(merge_common.THIRD_PARTY_PROJECTS,
                                    deps_vars)

  for path in merge_info:
    # webkit needs special handling as we have a local mirror
    local_mirrored = path == 'third_party/WebKit'
    url = merge_info[path]['url']
    sha1 = merge_info[path]['sha1']
    dest_dir = os.path.join(merge_common.REPOSITORY_ROOT, path)
    if local_mirrored:
      remote = 'history'
    else:
      remote = 'goog'
    merge_common.GetCommandStdout(['git', 'checkout',
                                   branch_create_flag, branch_name,
                                   '-t', remote + '/' + target],
                                  cwd=dest_dir)
    if not local_mirrored or not root_sha1:
      logging.debug('Fetching project %s at %s ...', path, sha1)
      merge_common.GetCommandStdout(['git', 'fetch', url, sha1], cwd=dest_dir)
    if merge_common.GetCommandStdout(['git', 'rev-list', '-1', 'HEAD..' + sha1],
                                     cwd=dest_dir):
      logging.debug('Merging project %s at %s ...', path, sha1)
      # Merge conflicts make git merge return 1, so ignore errors
      merge_common.GetCommandStdout(['git', 'merge', '--no-commit', sha1],
                                    cwd=dest_dir, ignore_errors=True)
      merge_common.CheckNoConflictsAndCommitMerge(
          'Merge %s from %s at %s\n\n%s' % (path, url, sha1, AUTOGEN_MESSAGE),
          cwd=dest_dir, unattended=unattended)
    else:
      logging.debug('No new commits to merge in project %s', path)

  # Handle root repository separately.
  merge_common.GetCommandStdout(['git', 'checkout',
                                 branch_create_flag, branch_name,
                                 '-t', 'history/' + target])
  if not root_sha1:
    merge_info = _GetProjectMergeInfo([''], deps_vars)
    url = merge_info['']['url']
    root_sha1 = merge_info['']['sha1']
    merge_common.GetCommandStdout(['git', 'fetch', url, root_sha1])
  logging.debug('Merging Chromium at %s ...', root_sha1)
  # Merge conflicts make git merge return 1, so ignore errors
  merge_common.GetCommandStdout(['git', 'merge', '--no-commit', root_sha1],
                                ignore_errors=True)
  merge_common.CheckNoConflictsAndCommitMerge(
      'Merge Chromium at %s (%s)\n\n%s'
      % (version, root_sha1, AUTOGEN_MESSAGE), unattended=unattended)

  logging.debug('Getting directories to exclude ...')

  # We import this now that we have merged the latest version.
  # It imports to a global in order that it can be used to generate NOTICE
  # later. We also disable writing bytecode to keep the source tree clean.
  sys.path.append(os.path.join(merge_common.REPOSITORY_ROOT, 'android_webview',
                               'tools'))
  sys.dont_write_bytecode = True
  global webview_licenses
  import webview_licenses
  import known_issues

  for path, exclude_list in known_issues.KNOWN_INCOMPATIBLE.iteritems():
    logging.debug('  %s', '\n  '.join(os.path.join(path, x) for x in
                                      exclude_list))
    dest_dir = os.path.join(merge_common.REPOSITORY_ROOT, path)
    merge_common.GetCommandStdout(['git', 'rm', '-rf', '--ignore-unmatch'] +
                                  exclude_list, cwd=dest_dir)
    if _ModifiedFilesInIndex(dest_dir):
      merge_common.GetCommandStdout(['git', 'commit', '-m',
                                     'Exclude unwanted directories'],
                                    cwd=dest_dir)


def _CheckLicenses():
  """Check that no incompatibly licensed directories exist."""
  directories_left_over = webview_licenses.GetIncompatibleDirectories()
  if directories_left_over:
    raise merge_common.TemporaryMergeError(
        'Incompatibly licensed directories remain: ' +
        '\n'.join(directories_left_over))


def _GenerateMakefiles(version, unattended):
  """Run gyp to generate the Android build system makefiles.

  Args:
    version: The version to mention in generated commit messages.
    unattended: Run in unattended mode.
  """
  logging.debug('Generating makefiles ...')

  # TODO(torne): The .tmp files are generated by
  # third_party/WebKit/Source/WebCore/WebCore.gyp/WebCore.gyp into the source
  # tree. We should avoid this, or at least use a more specific name to avoid
  # accidentally removing or adding other files.
  for path in merge_common.ALL_PROJECTS:
    dest_dir = os.path.join(merge_common.REPOSITORY_ROOT, path)
    merge_common.GetCommandStdout(['git', 'rm', '--ignore-unmatch',
                                   'GypAndroid.*.mk', '*.target.*.mk',
                                   '*.host.*.mk', '*.tmp'], cwd=dest_dir)

  try:
    merge_common.GetCommandStdout(['android_webview/tools/gyp_webview', 'all'])
  except merge_common.MergeError as e:
    if not unattended:
      raise
    else:
      for path in merge_common.ALL_PROJECTS:
        merge_common.GetCommandStdout(
            ['git', 'reset', '--hard'],
            cwd=os.path.join(merge_common.REPOSITORY_ROOT, path))
      raise merge_common.TemporaryMergeError('Makefile generation failed: ' +
                                             str(e))

  for path in merge_common.ALL_PROJECTS:
    dest_dir = os.path.join(merge_common.REPOSITORY_ROOT, path)
    # git add doesn't have an --ignore-unmatch so we have to do this instead:
    merge_common.GetCommandStdout(['git', 'add', '-f', 'GypAndroid.*.mk'],
                                  ignore_errors=True, cwd=dest_dir)
    merge_common.GetCommandStdout(['git', 'add', '-f', '*.target.*.mk'],
                                  ignore_errors=True, cwd=dest_dir)
    merge_common.GetCommandStdout(['git', 'add', '-f', '*.host.*.mk'],
                                  ignore_errors=True, cwd=dest_dir)
    merge_common.GetCommandStdout(['git', 'add', '-f', '*.tmp'],
                                  ignore_errors=True, cwd=dest_dir)
    # Only try to commit the makefiles if something has actually changed.
    if _ModifiedFilesInIndex(dest_dir):
      merge_common.GetCommandStdout(
          ['git', 'commit', '-m',
           'Update makefiles after merge of Chromium at %s\n\n%s' %
           (version, AUTOGEN_MESSAGE)], cwd=dest_dir)


def _ModifiedFilesInIndex(cwd=merge_common.REPOSITORY_ROOT):
  """Returns true if git's index contains any changes."""
  status = merge_common.GetCommandStdout(['git', 'status', '--porcelain'],
                                         cwd=cwd)
  return re.search(r'^[MADRC]', status, flags=re.MULTILINE) is not None


def _GenerateNoticeFile(version):
  """Generates and commits a NOTICE file containing code licenses.

  This covers all third-party code (from Android's perspective) that lives in
  the Chromium tree.

  Args:
    version: The version to mention in generated commit messages.
  """
  logging.debug('Regenerating NOTICE file ...')

  contents = webview_licenses.GenerateNoticeFile()

  with open(os.path.join(merge_common.REPOSITORY_ROOT, 'NOTICE'), 'w') as f:
    f.write(contents)
  merge_common.GetCommandStdout(['git', 'add', 'NOTICE'])
  # Only try to commit the NOTICE update if the file has actually changed.
  if _ModifiedFilesInIndex():
    merge_common.GetCommandStdout([
        'git', 'commit', '-m',
        'Update NOTICE file after merge of Chromium at %s\n\n%s'
        % (version, AUTOGEN_MESSAGE)])


def _GenerateLastChange(version):
  """Write a build/util/LASTCHANGE file containing the current revision.

  The revision number is compiled into the binary at build time from this file.

  Args:
    version: The version to mention in generated commit messages.
  """
  logging.debug('Updating LASTCHANGE ...')
  svn_revision, sha1 = _GetSVNRevisionAndSHA1('HEAD', 'HEAD')
  with open(os.path.join(merge_common.REPOSITORY_ROOT, 'build/util/LASTCHANGE'),
            'w') as f:
    f.write('LASTCHANGE=%s\n' % svn_revision)
  merge_common.GetCommandStdout(['git', 'add', '-f', 'build/util/LASTCHANGE'])
  logging.debug('Updating LASTCHANGE.blink ...')
  with open(os.path.join(merge_common.REPOSITORY_ROOT,
                         'build/util/LASTCHANGE.blink'), 'w') as f:
    f.write('LASTCHANGE=%s\n' % _GetBlinkRevision())
  merge_common.GetCommandStdout(['git', 'add', '-f',
                                 'build/util/LASTCHANGE.blink'])
  if _ModifiedFilesInIndex():
    merge_common.GetCommandStdout([
        'git', 'commit', '-m',
        'Update LASTCHANGE file after merge of Chromium at %s\n\n%s'
        % (version, AUTOGEN_MESSAGE)])


def GetLKGR():
  """Fetch the last known good release from Chromium's dashboard.

  Returns:
    The last known good SVN revision.
  """
  with contextlib.closing(
      urllib2.urlopen('https://chromium-status.appspot.com/lkgr')) as lkgr:
    return int(lkgr.read())


def GetHEAD():
  """Fetch the latest HEAD revision from the git mirror of the Chromium svn
  repo.

  Returns:
    The latest HEAD SVN revision.
  """
  (svn_revision, root_sha1) = _GetSVNRevisionAndSHA1(SRC_GIT_BRANCH,
                                                     'HEAD')
  return int(svn_revision)


def _ParseSvnRevisionFromGitCommitMessage(commit_message):
  return re.search(r'^git-svn-id: .*@([0-9]+)', commit_message,
                   flags=re.MULTILINE).group(1)


def _GetSVNRevisionFromSha(sha1):
  commit = merge_common.GetCommandStdout([
      'git', 'show', '--format=%H%n%b', sha1])
  return _ParseSvnRevisionFromGitCommitMessage(commit)


def _GetSVNRevisionAndSHA1(git_branch, svn_revision):
  logging.debug('Getting SVN revision and SHA1 ...')

  if svn_revision == 'HEAD':
    # Just use the latest commit.
    commit = merge_common.GetCommandStdout([
        'git', 'log', '-n1', '--grep=git-svn-id:', '--format=%H%n%b',
        git_branch])
    sha1 = commit.split()[0]
    svn_revision = _ParseSvnRevisionFromGitCommitMessage(commit)
    return (svn_revision, sha1)

  if svn_revision is None:
    # Fetch LKGR from upstream.
    svn_revision = GetLKGR()
  output = merge_common.GetCommandStdout([
      'git', 'log', '--grep=git-svn-id: .*@%s' % svn_revision,
      '--format=%H', git_branch])
  if not output:
    raise merge_common.TemporaryMergeError('Revision %s not found in git repo.'
                                           % svn_revision)
  # The log grep will sometimes match reverts/reapplies of commits. We take the
  # oldest (last) match because the first time it appears in history is
  # overwhelmingly likely to be the correct commit.
  sha1 = output.split()[-1]
  return (svn_revision, sha1)


def _GetBlinkRevision():
  commit = merge_common.GetCommandStdout([
      'git', 'log', '-n1', '--grep=git-svn-id:', '--format=%H%n%b'],
      cwd=os.path.join(merge_common.REPOSITORY_ROOT, 'third_party', 'WebKit'))
  return _ParseSvnRevisionFromGitCommitMessage(commit)


def Snapshot(svn_revision, root_sha1, release, target, unattended,
             buildspec_url):
  """Takes a snapshot of the Chromium tree and merges it into Android.

  Android makefiles and a top-level NOTICE file are generated and committed
  after the merge.

  Args:
    svn_revision: The SVN revision in the Chromium repository to merge from.
    root_sha1: The sha1 in the Chromium git mirror to merge from.
    release: The Chromium release version to merge from (e.g. "30.0.1599.20").
             Only one of svn_revision, root_sha1 and release should be
             specified.
    target: The target branch to merge to.
    unattended: Run in unattended mode.
    buildspec_url: URL for buildspec repository, used when merging a release.

  Returns:
    True if new commits were merged; False if no new commits were present.
  """
  if svn_revision:
    svn_revision, root_sha1 = _GetSVNRevisionAndSHA1(SRC_GIT_BRANCH,
                                                     svn_revision)
  elif root_sha1:
    svn_revision = _GetSVNRevisionFromSha(root_sha1)

  if svn_revision and root_sha1:
    version = svn_revision
    if not merge_common.GetCommandStdout(['git', 'rev-list', '-1',
                                          'HEAD..' + root_sha1]):
      logging.info('No new commits to merge at %s (%s)',
                   svn_revision, root_sha1)
      return False
  elif release:
    version = release
    root_sha1 = None
  else:
    raise merge_common.MergeError('No merge source specified')

  logging.info('Snapshotting Chromium at %s (%s)', version, root_sha1)

  # 1. Merge, accounting for excluded directories
  _MergeProjects(version, root_sha1, target, unattended, buildspec_url)

  # 2. Generate Android makefiles
  _GenerateMakefiles(version, unattended)

  # 3. Check for incompatible licenses
  _CheckLicenses()

  # 4. Generate Android NOTICE file
  _GenerateNoticeFile(version)

  # 5. Generate LASTCHANGE file
  _GenerateLastChange(version)

  return True


def Push(version, target):
  """Push the finished snapshot to the Android repository."""
  src = 'merge-from-chromium-%s' % version
  # Use forced pushes ('+' prefix) for the temporary and archive branches in
  # case they already got updated by a previous (possibly failed?) merge, but
  # do not force push to the real master-chromium branch as this could erase
  # downstream changes.
  refspecs = ['%s:%s' % (src, target),
              '+%s:refs/archive/chromium-%s' % (src, version)]
  if target == 'master-chromium':
    refspecs.insert(0, '%s:master-chromium-merge' % src)
  for refspec in refspecs:
    logging.debug('Pushing to server (%s) ...' % refspec)
    for path in merge_common.ALL_PROJECTS:
      if path in merge_common.PROJECTS_WITH_FLAT_HISTORY:
        remote = 'history'
      else:
        remote = 'goog'
      logging.debug('Pushing %s', path)
      dest_dir = os.path.join(merge_common.REPOSITORY_ROOT, path)
      merge_common.GetCommandStdout(['git', 'push', remote, refspec],
                                    cwd=dest_dir)


def main():
  parser = optparse.OptionParser(usage='%prog [options]')
  parser.epilog = ('Takes a snapshot of the Chromium tree at the specified '
                   'Chromium SVN revision and merges it into this repository. '
                   'Paths marked as excluded for license reasons are removed '
                   'as part of the merge. Also generates Android makefiles and '
                   'generates a top-level NOTICE file suitable for use in the '
                   'Android build.')
  parser.add_option(
      '', '--svn_revision',
      default=None,
      help=('Merge to the specified chromium SVN revision, rather than using '
            'the current LKGR. Can also pass HEAD to merge from tip of tree. '
            'Only one of svn_revision, sha1 and release should be specified'))
  parser.add_option(
      '', '--sha1',
      default=None,
      help=('Merge to the specified chromium sha1 revision from ' + SRC_GIT_BRANCH
            + ' branch, rather than using the current LKGR. Only one of'
            'svn_revision, sha1 and release should be specified.'))
  parser.add_option(
      '', '--release',
      default=None,
      help=('Merge to the specified chromium release buildspec (e.g. '
            '"30.0.1599.20"). Only one of svn_revision, sha1 and release '
            'should be specified.'))
  parser.add_option(
      '', '--buildspec_url',
      default=None,
      help=('Git URL for buildspec repository.'))
  parser.add_option(
      '', '--target',
      default='master-chromium', metavar='BRANCH',
      help=('Target branch to push to. Defaults to master-chromium.'))
  parser.add_option(
      '', '--push',
      default=False, action='store_true',
      help=('Push the result of a previous merge to the server. Note '
            'svn_revision must be given.'))
  parser.add_option(
      '', '--get_lkgr',
      default=False, action='store_true',
      help=('Just print the current LKGR on stdout and exit.'))
  parser.add_option(
      '', '--get_head',
      default=False, action='store_true',
      help=('Just print the current HEAD revision on stdout and exit.'))
  parser.add_option(
      '', '--unattended',
      default=False, action='store_true',
      help=('Run in unattended mode.'))
  parser.add_option(
      '', '--no_changes_exit',
      default=0, type='int',
      help=('Exit code to use if there are no changes to merge, for scripts.'))
  (options, args) = parser.parse_args()
  if args:
    parser.print_help()
    return 1

  if 'ANDROID_BUILD_TOP' not in os.environ:
    print >>sys.stderr, 'You need to run the Android envsetup.sh and lunch.'
    return 1

  logging.basicConfig(format='%(message)s', level=logging.DEBUG,
                      stream=sys.stdout)

  if options.get_lkgr:
    print GetLKGR()
  elif options.get_head:
    logging.disable(logging.CRITICAL)  # Prevent log messages
    print GetHEAD()
  elif options.push:
    if options.release:
      Push(options.release, options.target)
    elif options.svn_revision:
      Push(options.svn_revision, options.target)
    else:
      print >>sys.stderr, 'You need to pass the version to push.'
      return 1
  else:
    if not Snapshot(options.svn_revision, options.sha1, options.release,
                    options.target, options.unattended, options.buildspec_url):
      return options.no_changes_exit

  return 0

if __name__ == '__main__':
  sys.exit(main())
