# 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.

"""This module allows adding and deleting of projects to the local manifest."""

import logging
import platform
import optparse
import os
import sys
import xml.etree.ElementTree as ElementTree
from chromite.lib import cros_build_lib
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, *projects):
  """Enable the given manifest groups for the configured repository."""

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

  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 main(argv):
  parser = optparse.OptionParser(usage='usage: %prog add [options] <name> '
                                       '<--workon | <path> --remote <remote> >')
  parser.add_option('-w', '--workon', action='store_true', dest='workon',
                    default=False, help='Is this a workon package?')
  parser.add_option('-r', '--remote', dest='remote',
                    default=None)
  parser.add_option('-v', '--revision', dest='revision',
                    default=None,
                    help="Use to override the manifest defined default "
                    "revision used for a given project.")
  parser.add_option('--upgrade-minilayout', default=False, action='store_true',
                    help="Upgrade a minilayout checkout into a full.xml "
                    "checkout utilizing manifest groups.")
  (options, args) = 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.upgrade_minilayout:
    if args:
      parser.error("--upgrade-minilayout takes no arguments.")
    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.warn(
        "Your repository checkout is using the old minilayout.xml workflow; "
        "auto-upgrading it.")
    cros_build_lib.RunCommand(
        [sys.argv[0], '--upgrade-minilayout'], cwd=os.getcwd(),
         print_cmd=False)

  if not args:
    parser.error("No command specified.")
  elif args[0] != 'add':
    parser.error("Only supported subcommand is add right now.")
  elif options.workon:
    if len(args) != 2:
      parser.error(
          "Argument count is wrong for --workon; must be add <project>")
    name, path = args[1], None
  else:
    if options.remote is None:
      parser.error('Adding non-workon projects requires a remote.')
    elif len(args) != 3:
      parser.error(
          "Argument count is wrong for non-workon mode; "
          "must be add <project> <path> --remote <remote-arg>")
    name, path = args[1:]

  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
