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

"""Generates a sysroot tarball for building a specific package.

Meant for use after setup_board and build_packages have been run.
"""

from __future__ import print_function

import os

from chromite.cbuildbot import constants
from chromite.lib import cros_build_lib
from chromite.lib import commandline
from chromite.lib import osutils
from chromite.lib import sudo
from chromite.lib import sysroot_lib

DEFAULT_NAME = 'sysroot_%(package)s.tar.xz'
PACKAGE_SEPARATOR = '/'
SYSROOT = 'sysroot'


def ParseCommandLine(argv):
  """Parse args, and run environment-independent checks."""
  parser = commandline.ArgumentParser(description=__doc__)
  parser.add_argument('--board', required=True,
                      help=('The board to generate the sysroot for.'))
  parser.add_argument('--package', required=True,
                      help=('The package to generate the sysroot for.'))
  parser.add_argument('--out-dir', type='path', required=True,
                      help='Directory to place the generated tarball.')
  parser.add_argument('--out-file',
                      help=('The name to give to the tarball.  Defaults to %r.'
                            % DEFAULT_NAME))
  options = parser.parse_args(argv)

  if not options.out_file:
    options.out_file = DEFAULT_NAME % {
        'package': options.package.replace(PACKAGE_SEPARATOR, '_')
    }

  return options


class GenerateSysroot(object):
  """Wrapper for generation functionality."""

  PARALLEL_EMERGE = os.path.join(constants.CHROMITE_BIN_DIR, 'parallel_emerge')

  def __init__(self, sysroot, options):
    """Initialize

    Args:
      sysroot: Path to sysroot.
      options: Parsed options.
    """
    self.sysroot = sysroot
    self.options = options
    self.extra_env = {'ROOT': self.sysroot, 'USE': os.environ.get('USE', '')}

  def _Emerge(self, *args, **kwargs):
    """Emerge the given packages using parallel_emerge."""
    cmd = [self.PARALLEL_EMERGE, '--board=%s' % self.options.board,
           '--usepkgonly', '--noreplace'] + list(args)
    kwargs.setdefault('extra_env', self.extra_env)
    cros_build_lib.SudoRunCommand(cmd, **kwargs)

  def _InstallToolchain(self):
    # Create the sysroot's config.
    sysroot = sysroot_lib.Sysroot(self.sysroot)
    sysroot.WriteConfig(sysroot.GenerateBoardConfig(self.options.board))
    cros_build_lib.RunCommand(
        [os.path.join(constants.CROSUTILS_DIR, 'install_toolchain'),
         '--noconfigure', '--sysroot', self.sysroot])

  def _InstallKernelHeaders(self):
    self._Emerge('sys-kernel/linux-headers')

  def _InstallBuildDependencies(self):
    # Calculate buildtime deps that are not runtime deps.
    raw_sysroot = cros_build_lib.GetSysroot(board=self.options.board)
    cmd = ['qdepends', '-q', '-C', self.options.package]
    output = cros_build_lib.RunCommand(
        cmd, extra_env={'ROOT': raw_sysroot}, capture_output=True).output

    if output.count('\n') > 1:
      raise AssertionError('Too many packages matched given package pattern')

    # qdepend outputs "package: deps", so only grab the deps.
    atoms = output.partition(':')[2].split()

    # Install the buildtime deps.
    if atoms:
      self._Emerge(*atoms)

  def _CreateTarball(self):
    target = os.path.join(self.options.out_dir, self.options.out_file)
    cros_build_lib.CreateTarball(target, self.sysroot, sudo=True)

  def Perform(self):
    """Generate the sysroot."""
    self._InstallToolchain()
    self._InstallKernelHeaders()
    self._InstallBuildDependencies()
    self._CreateTarball()


def FinishParsing(options):
  """Run environment dependent checks on parsed args."""
  target = os.path.join(options.out_dir, options.out_file)
  if os.path.exists(target):
    cros_build_lib.Die('Output file %r already exists.' % target)

  if not os.path.isdir(options.out_dir):
    cros_build_lib.Die(
        'Non-existent directory %r specified for --out-dir' % options.out_dir)


def main(argv):
  options = ParseCommandLine(argv)
  FinishParsing(options)

  cros_build_lib.AssertInsideChroot()

  with sudo.SudoKeepAlive(ttyless_sudo=False):
    with osutils.TempDir(set_global=True, sudo_rm=True) as tempdir:
      sysroot = os.path.join(tempdir, SYSROOT)
      os.mkdir(sysroot)
      GenerateSysroot(sysroot, options).Perform()
