# -*- coding: utf-8 -*-
# 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 sys
import xml.etree.ElementTree as ElementTree

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


assert sys.version_info >= (3, 6), 'This module requires Python 3.6+'


class LocalManifest(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):
      return cls(osutils.ReadFile(path))
    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, encoding=repo_manifest.TOSTRING_ENCODING)

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


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

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

  git_config = options.git_config

  cmd = ['config', '-f', git_config, '--get', 'manifest.groups']
  enabled_groups = git.RunGit('.', cmd, check=False).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 _AssertNotMiniLayout():
  cros_build_lib.Die(
      'Your repository checkout is using the old minilayout.xml workflow; '
      'Autoupdate is no longer supported, reinstall your tree.')


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

  # Subparsers are required by default under Python 2.  Python 3 changed to
  # not required, but didn't include a required option until 3.7.  Setting
  # the required member works in all versions (and setting dest name).
  subparsers = parser.add_subparsers(dest='command')
  subparsers.required = True

  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('--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.')

  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.local_manifest_path = os.path.join(repo_dir, 'local_manifest.xml')

  manifest_sym_path = os.path.join(repo_dir, 'manifest.xml')
  if os.path.basename(os.path.realpath(manifest_sym_path)) == 'minilayout.xml':
    _AssertNotMiniLayout()

  # 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 = git.ManifestCheckout(os.getcwd())
  main_element = main_manifest.FindCheckouts(name)
  if path is not None:
    main_element_from_path = main_manifest.FindCheckoutFromPath(
        path, strict=False)
    if main_element_from_path is not None:
      main_element.append(main_element_from_path)

  local_manifest = LocalManifest.FromPath(options.local_manifest_path)

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

  elif main_element:
    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, [checkout['name'] for checkout in main_element])
    else:
      # Conflict will occur; complain.
      parser.error('Requested project name=%r path=%r will conflict with '
                   'your current manifest %s' % (
                       name, path, main_manifest.manifest_path))

  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
