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

from __future__ import print_function

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, *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 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
