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

"""cros package: Create and use packages in bricks.

This command can be used for creating basic packages (ebuilds) in user bricks
and determining how they are built. The aim is not to contain ebuilds
management or hide them from the user, rather to help bootstrap and build an
elementary project more easily.
"""

from __future__ import print_function

import os

from chromite.cli import command
from chromite.lib import brick_lib
from chromite.lib import commandline
from chromite.lib import cros_build_lib
from chromite.lib import osutils
from chromite.lib import portage_util


# Ebuild template for source packages in user bricks.
_SOURCE_EBUILD_TEMPLATE = """EAPI="4"

CROS_WORKON_SRCPATH="%(src_path)s"

inherit cros-workon

DESCRIPTION="Package %(package_name)s of brick %(brick_name)s"
SRC_URI=""

# Please assign a proper license for your package. You may use a standard
# license (e.g. "BSD") or add a custom one. For documentation, see:
# https://devmanual.gentoo.org/eclass-reference/ebuild/index.html
LICENSE="None"
SLOT="0"
KEYWORDS="~*"

src_install() {
	# Pleaes add install commands for your package below. It is recommended
	# to use ebuild primitives like dobin, dosbin, dolib, and so on. For a
	# complete documentation of such promitives, see:
	# https://devmanual.gentoo.org/eclass-reference/ebuild/index.html
	# Once you are done, please remove the 'die' line below.
	die "Please add install commands; see instructions in the ebuild."
}
"""


@command.CommandDecorator('package')
class PackageCommand(command.CliCommand):
  """Create and manage packages."""

  EPILOG = """
To create a source package in a brick:
  cros package --create-source path/to/source foo-category/bar-package
To enable building a package from latest or stable ebuilds:
  cros package --enable latest foo-category/bar-package
  cros package --enable stable foo-category/bar-package
"""

  _GROUP_HAS_LATEST = '@has-latest'
  _GROUP_ONLY_LATEST = '@only-latest'

  def __init__(self, options):
    super(PackageCommand, self).__init__(options)
    self.brick = None

  @classmethod
  def AddParser(cls, parser):
    super(cls, PackageCommand).AddParser(parser)
    parser.add_argument('package_name', metavar='package',
                        help='Name of package (category/package). When using '
                        '--enable, %s applies to all packages that have a '
                        'latest ebuild; %s applies to packages that have only '
                        'a latest ebuild.' %
                        (cls._GROUP_HAS_LATEST, cls._GROUP_ONLY_LATEST))
    parser.add_argument('--brick',
                        help='The brick to use. Auto-detected by default.')
    parser.add_argument('--create-source', metavar='src_path',
                        help='Create package from code in specified path. Path '
                        'is relative to the brick\'s source root.')
    parser.add_argument('--enable', '-e', choices=('latest', 'stable'),
                        help='Build package(s) from latest/stable source.')
    parser.add_argument('--force', action='store_true',
                        help='Ignore checks, clobber everything.')

  def _CreateSource(self):
    """Create a source package."""
    src_path = self.options.create_source.rstrip(os.path.sep)

    # Extract the package category and name.
    pkg_attrs = portage_util.SplitCPV(self.options.package_name, strict=False)
    if not (pkg_attrs.category and pkg_attrs.package and not pkg_attrs.version):
      cros_build_lib.Die('Package name must be of the form category/package')
    pkg_category = pkg_attrs.category
    pkg_name = pkg_attrs.package

    # Check that the source directory exists.
    if not (self.options.force or
            os.path.isdir(os.path.join(self.brick.SourceDir(), src_path))):
      cros_build_lib.Die('Package source directory (%s) not found', src_path)

    # Do not clobber ebuild unless forced.
    ebuild_file = os.path.join(self.brick.OverlayDir(), pkg_category,
                               pkg_name, '%s-9999.ebuild' % pkg_name)
    if not self.options.force and os.path.exists(ebuild_file):
      cros_build_lib.Die('Package ebuild already exists')

    # Create the ebuild.
    ebuild_content = _SOURCE_EBUILD_TEMPLATE % {
        'src_path': src_path,
        'package_name': self.options.package_name,
        'brick_name': self.options.brick,
    }
    try:
      osutils.WriteFile(ebuild_file, ebuild_content, makedirs=True)
    except EnvironmentError as e:
      cros_build_lib.Die('Failed creating the package ebuild: %s', e)

    # Register category as needed.
    categories_file = os.path.join(self.brick.OverlayDir(), 'profiles',
                                   'categories')
    category_line = '%s\n' % pkg_category
    try:
      add_category = category_line not in open(categories_file).readlines()
    except IOError:
      add_category = True

    if add_category:
      osutils.WriteFile(categories_file, category_line, mode='a',
                        makedirs=True)

  def _EnableBuild(self):
    """Enable latest/stable build."""
    to_latest = self.options.enable == 'latest'
    cmd = ['cros_workon',
           'start' if to_latest else 'stop',
           '--brick=%s' % self.options.brick]

    if self.options.package_name == self._GROUP_HAS_LATEST:
      cmd.append('--all')
    elif self.options.package_name == self._GROUP_ONLY_LATEST:
      cmd.append('--workon_only')
    else:
      cmd.append(self.options.package_name)

    result = cros_build_lib.RunCommand(cmd, quiet=True, error_code_ok=True)
    if result.returncode:
      cros_build_lib.Die('Failed to %s latest build for %s:\n%s' %
                         ('enable' if to_latest else 'disable',
                          self.options.package_name, result.output))

  def _ReadOptions(self):
    """Process arguments and set variables, then freeze options."""
    if not self.options.brick:
      if not self.curr_brick_locator:
        cros_build_lib.Die('Brick not specified nor discovered')
      self.options.brick = self.curr_brick_locator
    try:
      self.brick = brick_lib.Brick(self.options.brick)
    except brick_lib.BrickNotFound:
      cros_build_lib.Die('Could not find brick %s' % self.options.brick)

    self.options.Freeze()

  def Run(self):
    """Dispatch the call to the right handler."""
    self._ReadOptions()
    commandline.RunInsideChroot(self, auto_detect_brick=True)
    if self.options.create_source:
      self._CreateSource()
    if self.options.enable:
      self._EnableBuild()
