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

"""Script to generate a sysroot tarball.

Script that generates a tarball containing changes that are needed to create a
complete sysroot from extracted prebuilt packages.
"""

from __future__ import print_function

import os

from chromite.cbuildbot import constants
from chromite.lib import commandline
from chromite.lib import cros_build_lib
from chromite.lib import osutils
from chromite.lib import portage_util

_CREATE_BATCH_CMD = ('rsync',)
_CREATE_BATCH_EXCLUDE = ('--exclude=/tmp/', '--exclude=/var/cache/',
                         '--exclude=/usr/local/autotest/packages**',
                         '--exclude=/packages/', '--exclude=**.pyc',
                         '--exclude=**.pyo')
# rsync is used in archive mode with no --times.
# --checksum is used to ensure 100% accuracy.
# --delete is used to account for files that may be deleted during emerge.
# Short version: rsync -rplgoDc --delete
_CREATE_BATCH_ARGS = ('--recursive', '--links', '--perms', '--group',
                     '--owner', '--devices', '--specials', '--checksum',
                     '--delete')

# We want to ensure that we use only binary packages. However,
# build_packages will try to rebuild any unbuilt packages. Ignore those through
# --norebuild.
_BUILD_PKGS_CMD = (os.path.join(constants.CROSUTILS_DIR, 'build_packages'),
                   '--skip_chroot_upgrade', '--norebuild', '--usepkgonly')


def CreateBatchFile(build_dir, out_dir, batch_file):
  """Creates a batch file using rsync between build_dir and out_dir.

  This batch file can be applied to any directory identical to out_dir, to make
  it identical to build_dir.

  Args:
    build_dir: Directory to rsync from.
    out_dir: Directory to rsync to.
    batch_file: Batch file to be created.
  """
  cmd = list(_CREATE_BATCH_CMD)
  cmd.extend(list(_CREATE_BATCH_EXCLUDE))
  cmd.extend(list(_CREATE_BATCH_ARGS))
  cmd.extend(['--only-write-batch=' + batch_file, build_dir + '/', out_dir])
  cros_build_lib.SudoRunCommand(cmd)


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('--out-dir', type=osutils.ExpandPath, required=True,
                      help='Directory to place the generated tarball.')
  parser.add_argument('--out-batch', default=constants.DELTA_SYSROOT_BATCH,
                      help='The name to give to the batch file. Defaults to %r.'
                            % constants.DELTA_SYSROOT_BATCH)
  parser.add_argument('--out-file', default=constants.DELTA_SYSROOT_TAR,
                      help='The name to give to the tarball. Defaults to %r.'
                            % constants.DELTA_SYSROOT_TAR)
  parser.add_argument('--skip-tests', action='store_false', default=True,
                      dest='build_tests',
                      help='If we should not build the autotests packages.')
  options = parser.parse_args(argv)

  return options


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 GenerateSysroot(sysroot, board, build_tests, unpack_only=False):
  """Create a sysroot using only binary packages from local binhost.

  Args:
    sysroot: Where we want to place the sysroot.
    board: Board we want to build for.
    build_tests: If we should include autotest packages.
    unpack_only: If we only want to unpack the binary packages, and not build
                 them.
  """
  osutils.SafeMakedirs(sysroot)
  if not unpack_only:
    cros_build_lib.RunCommand(
        [os.path.join(constants.CROSUTILS_DIR, 'install_toolchain'),
         '--noconfigure', '--board_root', sysroot, '--board', board])
  cmd = list(_BUILD_PKGS_CMD)
  cmd.extend(['--board_root', sysroot, '--board', board])
  if unpack_only:
    cmd.append('--unpackonly')
  if not build_tests:
    cmd.append('--nowithautotest')
  env = {'USE': os.environ.get('USE', ''),
         'PORTAGE_BINHOST': 'file://%s' % portage_util.GetBinaryPackageDir(
             sysroot=cros_build_lib.GetSysroot(board))}
  cros_build_lib.RunCommand(cmd, extra_env=env)


def main(argv):
  """Generate a tarball containing a sysroot that can be patched over
  extracted prebuilt package contents to create a complete sysroot.

  1. Unpack all packages for a board into an unpack_only sysroot directory.
  2. Emerge all packages for a board into a build sysroot directory.
  3. Create a batch file using:
    rsync -rplgoDc --delete --write-batch=<batch> <build_sys> <unpackonly_sys>
  4. Put the batch file inside a tarball.
  """
  options = _ParseCommandLine(argv)
  FinishParsing(options)

  cros_build_lib.AssertInsideChroot()

  with osutils.TempDir(set_global=False, sudo_rm=True) as tmp_dir:
    build_sysroot = os.path.join(tmp_dir, 'build-sys')
    unpackonly_sysroot = os.path.join(tmp_dir, 'tmp-sys')
    batch_filename = options.out_batch

    GenerateSysroot(unpackonly_sysroot, options.board, options.build_tests,
                    unpack_only=True)
    GenerateSysroot(build_sysroot, options.board, options.build_tests,
                    unpack_only=False)

    # Finally create batch file.
    CreateBatchFile(build_sysroot, unpackonly_sysroot,
                    os.path.join(tmp_dir, batch_filename))

    cros_build_lib.CreateTarball(
        os.path.join(options.out_dir, options.out_file), tmp_dir, sudo=True,
        inputs=[batch_filename])
