#!/usr/bin/python

# Copyright (c) 2013 The Chromium OS Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.

"""A tool that updates remotes in all historical manifests to point to GoB.

It clones manifest-versions repository, scans through all manifests there and
replaces known old gerrit/gerrit-int URLs with Gerrit on Borg ones.

It doesn't commit or push any changes, just updates files in a working
directory.
"""

import collections
import os

from xml.etree import ElementTree

from chromite.buildbot import cbuildbot_config
from chromite.buildbot import manifest_version
from chromite.lib import commandline
from chromite.lib import cros_build_lib
from chromite.lib import osutils


GOB_EXTERNAL = "https://chromium.googlesource.com"
GOB_INTERNAL = "https://chrome-internal.googlesource.com"


GERRIT_EXTERNAL = "https://chromium-review.googlesource.com"
GERRIT_INTERNAL = "https://chrome-internal-review.googlesource.com"


# Old fetch URL -> new fetch URL.
# Old fetch urls are found by grepping through manifest-versions repo.
FETCH_URLS = {
    'http://git.chromium.org': GOB_EXTERNAL,
    'http://git.chromium.org/git': GOB_EXTERNAL,
    'https://git.chromium.org/git': GOB_EXTERNAL,
    'ssh://gerrit.chromium.org:29418': GOB_EXTERNAL,
    'ssh://git@gitrw.chromium.org:9222': GOB_EXTERNAL,
    'ssh://gerrit-int.chromium.org:29419': GOB_INTERNAL,
}


# Old review URL -> new review URL.
REVIEW_URLS = {
    'gerrit.chromium.org/gerrit': GERRIT_EXTERNAL,
    'gerrit-int.chromium.org': GERRIT_INTERNAL,
}


# Single remote entry in a manifest.
Remote = collections.namedtuple('Remote', ['name', 'fetch', 'review'])


def EnumerateManifests(directory):
  """Yields paths to manifest files inside a directory."""
  for path, directories, files in os.walk(directory):
    # Find regular (not a symlink) xml files.
    for name in files:
      if not name.endswith('.xml'):
        continue
      full_path = os.path.join(path, name)
      if os.path.isfile(full_path) and not os.path.islink(full_path):
        yield full_path
    # Skip 'hidden' directories.
    for hidden in [name for name in directories if name.startswith('.')]:
      directories.remove(hidden)


def UpdateRemotes(manifest):
  """Updates remotes in manifest to use Gerrit on Borg URLs.

  Args:
    manifest: Path to manifest file to modify in place.

  Returns:
    True if file was modified.
  """
  # Read manifest file as str.
  body = osutils.ReadFile(manifest)
  original = body

  # Update fetch="..." entries.
  for old, new in FETCH_URLS.iteritems():
    body = body.replace('fetch="%s"' % old, 'fetch="%s"' % new)

  # Update review="..." entries.
  for old, new in REVIEW_URLS.iteritems():
    body = body.replace('review="%s"' % old, 'review="%s"' % new)

  # Write back only if modified.
  if original != body:
    osutils.WriteFile(manifest, body)
    return True

  return False


def GetRemotes(manifest):
  """Returns list of remotes referenced in manifest.

  Args:
    manifest: Path to manifest file to scan for remotes.

  Returns:
    List of Remote tuples.
  """
  doc = ElementTree.parse(manifest)
  root = doc.getroot()
  return [Remote(remote.attrib['name'], remote.attrib['fetch'],
      remote.attrib.get('review')) for remote in root.findall('remote')]


def GetParser():
  """Creates the argparse parser."""
  parser = commandline.ArgumentParser(description=__doc__)
  parser.add_argument('--skip-update', action='store_true', default=False,
      help='Do not revert versions manifest checkout to original state')
  parser.add_argument('--remotes-summary', action='store_true', default=False,
      help='Scan all manifests and print all various remotes found in them')
  parser.add_argument('manifest_versions_dir', type='path',
      help='Directory to checkout manifest versions repository into')
  return parser


def main(argv):
  parser = GetParser()
  options = parser.parse_args(argv)

  # Clone manifest-versions repository.
  manifest_repo_url = cbuildbot_config.GetManifestVersionsRepoUrl(
      internal_build=True, read_only=False)
  if not options.skip_update:
    manifest_version.RefreshManifestCheckout(
        options.manifest_versions_dir, manifest_repo_url)

  if options.remotes_summary:
    # Find all unique remotes.
    cros_build_lib.Info('Scanning manifests for remotes...')
    remotes = set()
    for manifest in EnumerateManifests(options.manifest_versions_dir):
      remotes.update(GetRemotes(manifest))
    # Pretty print a table.
    print 'Remotes found:'
    row_formatter = lambda a, b, c: ''.join(
        [a, ' ' * (16 - len(a)), b, ' ' * (45 - len(b)), c])
    print row_formatter('Name', 'Remote', 'Review')
    print '-' * 80
    for remote in sorted(remotes):
      print row_formatter(remote.name, remote.fetch, remote.review or '')
    return 0

  cros_build_lib.Info('Updating manifests...')
  up_to_date = True
  for manifest in EnumerateManifests(options.manifest_versions_dir):
    if UpdateRemotes(manifest):
      up_to_date = False
      cros_build_lib.Info('Updated manifest: %s', manifest)

  if up_to_date:
    cros_build_lib.Info('All manifests are up to date')
  else:
    cros_build_lib.Info('Done')

  return 0
