#!/usr/bin/env python2
# 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
"""

from __future__ import print_function

__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):
  """Exception used to fail out for a bad environment."""


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.
    suppress: List of repos already seen (and so to ignore).

  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
    initial_reference: 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))
