#!/usr/bin/python

# Copyright (c) 2012 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.


"""
Functionality for mangling repository checkouts that are shared

In particular, this in combination w/ enter_chroot's mount binding, allows
us to access the same repo from inside and outside a chroot at the same time
"""

__all__ = ('RebuildRepoCheckout',)

import sys
import os
import shutil
import errno

_path = os.path.realpath(__file__)
_path = os.path.normpath(os.path.join(os.path.dirname(_path), '..', '..'))
sys.path.insert(0, _path)
del _path

from chromite.lib import cros_build_lib
from chromite.lib import git
from chromite.lib import osutils


_CACHE_NAME = '.cros_projects.list'


def _FilterNonExistentProjects(project_dir, projects):
  for project in projects:
    if os.path.exists(os.path.join(project_dir, project)):
      yield project


def _CleanAlternates(projects, alt_root):
  alt_root = os.path.normpath(alt_root)

  projects = set(projects)
  # Ignore our cache.
  projects.add(_CACHE_NAME)
  required_directories = set(os.path.dirname(x) for x in projects)

  for abs_root, dirs, files in os.walk(alt_root):
    rel_root = abs_root[len(alt_root):].strip('/')

    if rel_root not in required_directories:
      shutil.rmtree(abs_root)
      dirs[:] = []
      continue

    if rel_root:
      for filename in files:
        if os.path.join(rel_root, filename) not in projects:
          os.unlink(os.path.join(abs_root, filename))


def _UpdateAlternatesDir(alternates_root, reference_maps, projects):
  for project in projects:
    alt_path = os.path.join(alternates_root, project)
    paths = []
    for k, v in reference_maps.iteritems():
      suffix = os.path.join('.repo', 'project-objects', project, 'objects')
      if os.path.exists(os.path.join(k, suffix)):
        paths.append(os.path.join(v, suffix))

    osutils.SafeMakedirs(os.path.dirname(alt_path))
    osutils.WriteFile(alt_path, '%s\n' % ('\n'.join(paths),), atomic=True)


def _UpdateGitAlternates(proj_root, projects):
  for project in projects:

    alt_path = os.path.join(proj_root, project, 'objects', 'info',
                            'alternates')
    tmp_path = '%s.tmp' % alt_path

    # Clean out any tmp files that may have existed prior.
    osutils.SafeUnlink(tmp_path)

    # The pathway is written relative to the alternates files absolute path;
    # literally, .repo/projects/chromite.git/objects/info/alternates.
    relpath = '../' * (project.count('/') + 4)
    relpath = os.path.join(relpath, 'alternates', project)

    osutils.SafeMakedirs(os.path.dirname(tmp_path))
    os.symlink(relpath , tmp_path)
    os.rename(tmp_path, alt_path)


def _GetProjects(repo_root):
  # Note that we cannot rely upon projects.list, nor repo list, nor repo forall
  # here to be authoritive.
  # if we rely on the manifest contents, the local tree may not yet be
  # updated- thus if we drop the alternate for that project, that project is no
  # longer usable (which can tick off repo sync).
  # Thus, we just iterate over the raw underlying projects store, and generate
  # alternates for that; we regenerate based on either the manifest changing,
  # local_manifest having changed, or projects.list having changed (which
  # occurs during partial local repo syncs; aka repo sync chromite for
  # example).
  # Finally, note we have to truncate our mtime awareness to just integers;
  # this is required since utime isn't guaranteed to set floats, despite our
  # being able to get a float back from stat'ing.

  manifest_xml = os.path.join(repo_root, 'manifest.xml')
  times = [os.lstat(manifest_xml).st_mtime,
           os.stat(manifest_xml).st_mtime]
  for path in ('local_manifest.xml', 'project.list'):
    path = os.path.join(repo_root, path)
    if os.path.exists(path):
      times.append(os.stat(path).st_mtime)

  manifest_time = long(max(times))

  cache_path = os.path.join(repo_root, _CACHE_NAME)

  try:
    if long(os.stat(cache_path).st_mtime) == manifest_time:
      return osutils.ReadFile(cache_path).split()
  except EnvironmentError as e:
    if e.errno != errno.ENOENT:
      raise

  # The -a ! section of this find invocation is to block descent
  # into the actual git repository; for IO constrained systems,
  # this avoids a fairly large amount of inode/dentry load up.
  # TLDR; It's faster, don't remove it ;)
  data = cros_build_lib.RunCommand(
      ['find', './', '-type', 'd', '-name', '*.git', '-a',
       '!', '-wholename', '*/*.git/*', '-prune'],
      cwd=os.path.join(repo_root, 'project-objects'), capture_output=True)

  # Drop the leading ./ and the trailing .git
  data = [x[2:-4] for x in data.output.splitlines() if x]

  with open(cache_path, 'w') as f:
    f.write('\n'.join(sorted(data)))

  # Finally, mark the cache with the time of the manifest.xml we examined.
  os.utime(cache_path, (manifest_time, manifest_time))
  return data


class Failed(Exception):
  pass


def _RebuildRepoCheckout(target_root, reference_map,
                         alternates_dir):
  repo_root = os.path.join(target_root, '.repo')
  proj_root = os.path.join(repo_root, 'project-objects')

  manifest_path = os.path.join(repo_root, 'manifest.xml')
  if not os.path.exists(manifest_path):
    raise Failed('%r does not exist, thus cannot be a repo checkout' %
                 manifest_path)

  projects = ['%s.git' % x for x in _GetProjects(repo_root)]
  projects = _FilterNonExistentProjects(proj_root, projects)
  projects = list(sorted(projects))

  if not osutils.SafeMakedirs(alternates_dir, 0o775):
    # We know the directory exists; thus cleanse out
    # dead alternates.
    _CleanAlternates(projects, alternates_dir)

  _UpdateAlternatesDir(alternates_dir, reference_map, projects)
  _UpdateGitAlternates(proj_root, projects)


def WalkReferences(repo_root, max_depth=5, suppress=()):
  """Given a repo checkout root, find the repo's it references up to max_depth.

  Args:
    repo_root: The root of a repo checkout to start from
    max_depth: Git internally limits the max alternates depth to 5;
      this option exists to adjust how deep we're willing to look.

  Returns:
    List of repository roots required for this repo_root.
  """

  original_root = repo_root
  seen = set(os.path.abspath(x) for x in suppress)

  for _x in xrange(0, max_depth):
    repo_root = os.path.abspath(repo_root)

    if repo_root in seen:
      # Cyclic reference graph; break out of it, if someone induced this the
      # necessary objects should be in place.  If they aren't, really isn't
      # much that can be done.
      return

    yield repo_root
    seen.add(repo_root)
    base = os.path.join(repo_root, '.repo', 'manifests.git')
    result = git.RunGit(
        base, ['config', 'repo.reference'], error_code_ok=True)

    if result.returncode not in (0, 1):
      raise Failed('Unexpected returncode %i from examining %s git '
                   'repo.reference configuration' %
                   (result.returncode, base))

    repo_root = result.output.strip()
    if not repo_root:
      break

  else:
    raise Failed('While tracing out the references of %s, we recursed more '
                 'than the allowed %i times ending at %s'
                 % (original_root, max_depth, repo_root))


def RebuildRepoCheckout(repo_root, initial_reference,
                        chroot_reference_root=None):
  """Rebuild a repo checkout's 'alternate tree' rewriting the repo to use it

  Args:
    repo_root: absolute path to the root of a repository checkout
    reference_root: absolute path to the root of the repository that is
      shared
    chroot_reference_root: if given, repo_root will have it's chroot
      alternates tree configured with this pathway, enabling repo access to
      work from within the chroot.
  """

  reference_roots = list(WalkReferences(initial_reference,
                                        suppress=[repo_root]))

  # Always rebuild the external alternates for any operation; 1) we don't want
  # external out of sync from chroot, 2) if this is the first conversion, if
  # we only update chroot it'll break external access to the repo.
  reference_map = dict((x, x) for x in reference_roots)
  rebuilds = [('alternates', reference_map)]
  if chroot_reference_root:
    alternates_dir = 'chroot/alternates'
    base = os.path.join(chroot_reference_root, '.repo', 'chroot', 'external')
    reference_map = dict((x, '%s%i' % (base, idx + 1))
                         for idx, x in enumerate(reference_roots))
    rebuilds += [('chroot/alternates', reference_map)]

  for alternates_dir, reference_map in rebuilds:
    alternates_dir = os.path.join(repo_root, '.repo', alternates_dir)
    _RebuildRepoCheckout(repo_root,
                         reference_map,
                         alternates_dir)
  return reference_roots


if __name__ == '__main__':
  chroot_root = None
  if len(sys.argv) not in (3, 4):
    sys.stderr.write('Usage: %s <repository_root> <referenced_repository> '
                     '[path_from_within_the_chroot]\n' % (sys.argv[0],))
    sys.exit(1)
  if len(sys.argv) == 4:
    chroot_root = sys.argv[3]
  ret = RebuildRepoCheckout(sys.argv[1], sys.argv[2],
                            chroot_reference_root=chroot_root)
  print '\n'.join(ret)
