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

"""Manage projects in the local manifest."""

from __future__ import print_function

import platform
import os
import xml.etree.ElementTree as ElementTree

from chromite.lib import commandline
from chromite.lib import cros_build_lib
from chromite.lib import cros_logging as logging
from chromite.lib import git


class Manifest(object):
  """Class which provides an abstraction for manipulating the local manifest."""

  @classmethod
  def FromPath(cls, path, empty_if_missing=False):
    if os.path.isfile(path):
      with open(path) as f:
        return cls(f.read())
    elif empty_if_missing:
      cros_build_lib.Die('Manifest file, %r, not found' % path)
    return cls()

  def __init__(self, text=None):
    self._text = text or '<manifest>\n</manifest>'
    self.nodes = ElementTree.fromstring(self._text)

  def AddNonWorkonProject(self, name, path, remote=None, revision=None):
    """Add a new nonworkon project element to the manifest tree."""
    element = ElementTree.Element('project', name=name, path=path,
                                  remote=remote)
    element.attrib['workon'] = 'False'
    if revision is not None:
      element.attrib['revision'] = revision
    self.nodes.append(element)
    return element

  def GetProject(self, name, path=None):
    """Accessor method for getting a project node from the manifest tree.

    Returns:
      project element node from ElementTree, otherwise, None
    """
    if path is None:
      # Use a unique value that can't ever match.
      path = object()
    for project in self.nodes.findall('project'):
      if project.attrib['name'] == name or project.attrib['path'] == path:
        return project
    return None

  def ToString(self):
    # Reset the tail for each node, then just do a hacky replace.
    project = None
    for project in self.nodes.findall('project'):
      project.tail = '\n  '
    if project is not None:
      # Tweak the last project to not have the trailing space.
      project.tail = '\n'
    # Fix manifest tag text and tail.
    self.nodes.text = '\n  '
    self.nodes.tail = '\n'
    return ElementTree.tostring(self.nodes)

  def GetProjects(self):
    return list(self.nodes.findall('project'))


def _AddProjectsToManifestGroups(options, *args):
  """Enable the given manifest groups for the configured repository."""

  groups_to_enable = ['name:%s' % x for x in args]

  git_config = options.git_config

  cmd = ['config', '-f', git_config, '--get', 'manifest.groups']
  enabled_groups = git.RunGit('.', cmd, error_code_ok=True).output.split(',')

  # Note that ordering actually matters, thus why the following code
  # is written this way.
  # Per repo behaviour, enforce an appropriate platform group if
  # we're converting from a default manifest group to a limited one.
  # Finally, note we reprocess the existing groups; this is to allow
  # us to cleanup any user screwups, or our own screwups.
  requested_groups = (
      ['minilayout', 'platform-%s' % (platform.system().lower(),)] +
      enabled_groups + list(groups_to_enable))

  processed_groups = set()
  finalized_groups = []

  for group in requested_groups:
    if group not in processed_groups:
      finalized_groups.append(group)
      processed_groups.add(group)

  cmd = ['config', '-f', git_config, 'manifest.groups',
         ','.join(finalized_groups)]
  git.RunGit('.', cmd)


def _UpgradeMinilayout(options):
  """Convert a repo checkout away from minilayout.xml to default.xml."""

  full_tree = Manifest.FromPath(options.default_manifest_path)
  local_manifest_exists = os.path.exists(options.local_manifest_path)

  new_groups = []
  if local_manifest_exists:
    local_tree = Manifest.FromPath(options.local_manifest_path)
    # Identify which projects need to be transferred across.
    projects = local_tree.GetProjects()
    new_groups = [x.attrib['name'] for x in projects]
    allowed = set(x.attrib['name'] for x in full_tree.GetProjects())
    transferred = [x for x in projects if x.attrib['name'] in allowed]
    for project in transferred:
      # Mangle local_manifest object, removing those projects;
      # note we'll still be adding those projects to the default groups,
      # including those that didn't intersect the main manifest.
      local_tree.nodes.remove(project)

  _AddProjectsToManifestGroups(options, *new_groups)

  if local_manifest_exists:
    # Rewrite the local_manifest now; if there is no settings left in
    # the local_manifest, wipe it.
    if local_tree.nodes.getchildren():
      with open(options.local_manifest_path, 'w') as f:
        f.write(local_tree.ToString())
    else:
      os.unlink(options.local_manifest_path)

  # Finally, move the symlink.
  os.unlink(options.manifest_sym_path)
  os.symlink('manifests/default.xml', options.manifest_sym_path)
  logging.info("Converted the checkout to manifest groups based minilayout.")


def GetParser():
  """Return a command line parser."""
  parser = commandline.ArgumentParser(description=__doc__)

  subparsers = parser.add_subparsers(dest='command')

  subparser = subparsers.add_parser(
      'add',
      help='Add projects to the manifest.')
  subparser.add_argument('-w', '--workon', action='store_true',
                         default=False, help='Is this a workon package?')
  subparser.add_argument('-r', '--remote',
                         help='Remote project name (for non-workon packages).')
  subparser.add_argument('-v', '--revision',
                         help='Use to override the manifest defined default '
                              'revision used for a given project.')
  subparser.add_argument('project', help='Name of project in the manifest.')
  subparser.add_argument('path', nargs='?', help='Local path to the project.')

  subparser = subparsers.add_parser(
      'upgrade-minilayout',
      help='Upgrade a minilayout checkout into a full.xml checkout utilizing '
           'manifest groups.')

  return parser


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

  repo_dir = git.FindRepoDir(os.getcwd())
  if not repo_dir:
    parser.error("This script must be invoked from within a repository "
                 "checkout.")

  options.git_config = os.path.join(repo_dir, 'manifests.git', 'config')
  options.repo_dir = repo_dir
  options.local_manifest_path = os.path.join(repo_dir, 'local_manifest.xml')
  # This constant is used only when we're doing an upgrade away from
  # minilayout.xml to default.xml.
  options.default_manifest_path = os.path.join(repo_dir, 'manifests',
                                               'default.xml')
  options.manifest_sym_path = os.path.join(repo_dir, 'manifest.xml')

  active_manifest = os.path.basename(os.readlink(options.manifest_sym_path))
  upgrade_required = active_manifest == 'minilayout.xml'

  if options.command == 'upgrade-minilayout':
    if not upgrade_required:
      print("This repository checkout isn't using minilayout.xml; "
            "nothing to do")
    else:
      _UpgradeMinilayout(options)
    return 0
  elif upgrade_required:
    logging.warning(
        "Your repository checkout is using the old minilayout.xml workflow; "
        "auto-upgrading it.")
    main(['upgrade-minilayout'])

  # For now, we only support the add command.
  assert options.command == 'add'
  if options.workon:
    if options.path is not None:
      parser.error('Adding workon projects do not set project.')
  else:
    if options.remote is None:
      parser.error('Adding non-workon projects requires a remote.')
    if options.path is None:
      parser.error('Adding non-workon projects requires a path.')
  name = options.project
  path = options.path

  revision = options.revision
  if revision is not None:
    if (not git.IsRefsTags(revision) and
        not git.IsSHA1(revision)):
      revision = git.StripRefsHeads(revision, False)

  main_manifest = Manifest.FromPath(options.manifest_sym_path,
                                    empty_if_missing=False)
  local_manifest = Manifest.FromPath(options.local_manifest_path)

  main_element = main_manifest.GetProject(name, path=path)

  if options.workon:
    if main_element is None:
      parser.error('No project named %r in the default manifest.' % name)
    _AddProjectsToManifestGroups(options, main_element.attrib['name'])

  elif main_element is not None:
    if options.remote is not None:
      # Likely this project wasn't meant to be remote, so workon main element
      print("Project already exists in manifest. Using that as workon project.")
      _AddProjectsToManifestGroups(options, main_element.attrib['name'])
    else:
      # Conflict will occur; complain.
      parser.error("Requested project name=%r path=%r will conflict with "
                   "your current manifest %s" % (name, path, active_manifest))

  elif local_manifest.GetProject(name, path=path) is not None:
    parser.error("Requested project name=%r path=%r conflicts with "
                 "your local_manifest.xml" % (name, path))

  else:
    element = local_manifest.AddNonWorkonProject(name=name, path=path,
                                                 remote=options.remote,
                                                 revision=revision)
    _AddProjectsToManifestGroups(options, element.attrib['name'])

    with open(options.local_manifest_path, 'w') as f:
      f.write(local_manifest.ToString())
  return 0
