#!/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',
                                'releases/' + version + '/.DEPS.git',
                                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)
      fetch_args = ['git', 'fetch', url, sha1]
      merge_common.GetCommandStdout(fetch_args, 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): come up with a way to deal with hooks from DEPS properly

  # 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())
