#!/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.cbuildbot import cbuildbot_config
from chromite.cbuildbot 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
