# -*- coding: utf-8 -*-
# Copyright 2018 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 Chromium OS update for use by the update engine.

If a source .bin is specified, the update is assumed to be a delta update.
"""

from __future__ import print_function

import tempfile

from chromite.lib import constants
from chromite.lib import commandline
from chromite.lib import cros_build_lib
from chromite.lib import cros_logging as logging
from chromite.lib import osutils

from chromite.lib.paygen import partition_lib


_DELTA_GENERATOR = 'delta_generator'


def GenerateUpdatePayload(opts):
  """Generates the output files for the given commandline |opts|."""
  # TODO(tbrindus): we can support calling outside of chroot easily with
  #                 RunCommand, so we can remove this restriction.
  if opts.src_image and not opts.outside_chroot:
    # We need to be in the chroot for generating delta images. By specifying
    # --outside_chroot you can choose not to assert this, which will allow us to
    # run this script outside chroot. Running this script outside chroot
    # requires copying a delta_generator binary and some related shared
    # libraries.
    cros_build_lib.AssertInsideChroot()
  try:
    src_kernel_path = src_root_path = dst_kernel_path = dst_root_path = ''

    if opts.extract:
      if opts.src_image:
        src_kernel_path = opts.src_kern_path or 'old_kern.dat'
        src_root_path = opts.src_root_path or 'old_root.dat'
        partition_lib.ExtractKernel(opts.src_image, src_kernel_path)
        partition_lib.ExtractRoot(opts.src_image, src_root_path)
      if opts.image:
        dst_kernel_path = opts.kern_path or 'new_kern.dat'
        dst_root_path = opts.root_path or 'new_root.dat'
        partition_lib.ExtractKernel(opts.image, dst_kernel_path)
        partition_lib.ExtractRoot(opts.image, dst_root_path,
                                  opts.root_pretruncate_path)
      logging.info('Done extracting kernel/root')
      return

    delta, payload_type = (True, 'delta') if opts.src_image else (False, 'full')

    logging.info('Generating %s update', payload_type)

    src_kernel_path = ''
    src_root_path = ''
    if delta:
      if not opts.full_kernel:
        src_kernel_path = (opts.src_kern_path or
                           tempfile.NamedTemporaryFile().name)
        partition_lib.ExtractKernel(opts.src_image, src_kernel_path)
      else:
        logging.info('Generating full kernel update')

      src_root_path = opts.src_root_path or tempfile.NamedTemporaryFile().name
      partition_lib.ExtractRoot(opts.src_image, src_root_path)

    dst_kernel_path = opts.kern_path or tempfile.NamedTemporaryFile().name
    dst_root_path = opts.root_path or tempfile.NamedTemporaryFile().name
    partition_lib.ExtractKernel(opts.image, dst_kernel_path)
    partition_lib.ExtractRoot(opts.image, dst_root_path,
                              opts.root_pretruncate_path)

    # In major version 2 we need to explicity mark the postinst on the root
    # partition to run.
    postinst_config_path = tempfile.NamedTemporaryFile(prefix='postinst').name
    with open(postinst_config_path, 'w') as postinst_config:
      postinst_config.write('RUN_POSTINSTALL_root=true\n')

    generator_args = [
        # Common payload args:
        '--major_version=2',
        '--out_file=' + opts.output,
        '--private_key=' + (opts.private_key or ''),
        '--out_metadata_size_file=' + (opts.out_metadata_size_file or ''),
        # Target image args:
        '--partition_names=' + ':'.join(['root', 'kernel']),
        '--new_partitions=' + ':'.join([dst_root_path, dst_kernel_path]),
        '--new_postinstall_config_file=' + postinst_config_path,
        '--new_channel=' + opts.channel,
        '--new_board=' + opts.board,
        '--new_version=' + opts.version,
        '--new_key=' + opts.key,
        '--new_build_channel=' + opts.build_channel,
        '--new_build_version=' + opts.build_version,
    ]

    if delta:
      generator_args += [
          # Source image args:
          '--old_partitions=' + ':'.join([src_root_path, src_kernel_path]),
          '--old_channel=' + opts.src_channel,
          '--old_board=' + opts.src_board,
          '--old_version=' + opts.src_version,
          '--old_key=' + opts.src_key,
          '--old_build_channel=' + opts.src_build_channel,
          '--old_build_version=' + opts.src_build_version,
      ]

      # The passed chunk_size is only used for delta payload. Use
      # delta_generator's default if no value is provided.
      if opts.chunk_size:
        logging.info('Forcing chunk size to %d', opts.chunk_size)
        generator_args.append('--chunk_size=%d' % opts.chunk_size)

    # Add partition size. Only *required* for minor_version=1.
    # TODO(tbrindus): deprecate this when we deprecate minor version 1.
    dst_root_part_size = cros_build_lib.GetImageDiskPartitionInfo(
        opts.image, unit='B')[constants.PART_ROOT_A].size

    if dst_root_part_size:
      logging.info('Using rootfs partition size: %d', dst_root_part_size)
      generator_args.append('--rootfs_partition_size=%d' % dst_root_part_size)
    else:
      logging.info('Using the default partition size')

    cros_build_lib.RunCommand([_DELTA_GENERATOR] + generator_args)

    if opts.out_payload_hash_file or opts.out_metadata_hash_file:
      # The out_metadata_hash_file flag requires out_hash_file flag to be set
      # in delta_generator, if caller doesn't provide it, we set it to
      # /dev/null.
      out_payload_hash_file = opts.out_payload_hash_file or '/dev/null'

      # The manifest - unfortunately - contains two fields called
      # signature_offset and signature_size with data about how the manifest is
      # signed. This means we have to pass the signature size used. The value
      # 256 is the number of bytes the SHA-256 hash value of the manifest signed
      # with a 2048-bit RSA key occupies.
      generator_args = [
          '--in_file=' + opts.output,
          '--signature_size=256',
          '--out_hash_file=' + out_payload_hash_file,
          '--out_metadata_hash_file=' + (opts.out_metadata_hash_file or ''),
      ]
      cros_build_lib.RunCommand([_DELTA_GENERATOR] + generator_args)

    logging.info('Done generating %s update', payload_type)
  finally:
    if not opts.src_kern_path:
      osutils.SafeUnlink(src_kernel_path)
    if not opts.src_root_path:
      osutils.SafeUnlink(src_root_path)
    if not opts.kern_path:
      osutils.SafeUnlink(dst_kernel_path)
    if not opts.root_path:
      osutils.SafeUnlink(dst_root_path)


def ParseArguments(argv):
  """Returns a namespace for the CLI arguments."""
  parser = commandline.ArgumentParser(description=__doc__)
  parser.add_argument('--image', type='path',
                      help='The image that should be sent to clients.')
  parser.add_argument('--src_image', type='path',
                      help='A source image. If specified, this makes a delta '
                           'update.')
  parser.add_argument('--output', type='path', help='Output file.')
  parser.add_argument('--outside_chroot', action='store_true',
                      help='Running outside of chroot.')
  parser.add_argument('--private_key', type='path',
                      help='Path to private key in .pem format.')
  parser.add_argument('--out_payload_hash_file', type='path',
                      help='Path to output payload hash file.')
  parser.add_argument('--out_metadata_hash_file', type='path',
                      help='Path to output metadata hash file.')
  parser.add_argument('--out_metadata_size_file', type='path',
                      help='Path to output metadata size file.')
  parser.add_argument('--extract', action='store_true',
                      help='If set, extract old/new kernel/rootfs to '
                           '[old|new]_[kern|root].dat. Useful for debugging.')
  parser.add_argument('--full_kernel', action='store_true',
                      help='Generate a full kernel update even if generating a '
                           'delta update.')
  parser.add_argument('--chunk_size', type=int,
                      help='Delta payload chunk size (-1 means whole files).')

  # TODO(tbrindus): Remove --build_version and --src_build_version flags.
  src_group = parser.add_argument_group('Source options')
  src_group.add_argument('--src_channel', type=str, default='',
                         help='Channel of the src image.')
  src_group.add_argument('--src_board', type=str, default='',
                         help='Board of the src image.')
  src_group.add_argument('--src_version', type=str, default='',
                         help='Version of the src image.')
  src_group.add_argument('--src_key', type=str, default='',
                         help='Key of the src image.')
  src_group.add_argument('--src_build_channel', type=str, default='',
                         help='Channel of the build of the src image.')
  src_group.add_argument('--src_build_version', type=str, default='',
                         help='Channel of the build of the the src image.')

  dst_group = parser.add_argument_group('Target options')
  dst_group.add_argument('--channel', type=str, default='',
                         help='Channel of the target image.')
  dst_group.add_argument('--board', type=str, default='',
                         help='Board of the target image.')
  dst_group.add_argument('--version', type=str, default='',
                         help='Version of the target image.')
  dst_group.add_argument('--key', type=str, default='',
                         help='Key of the target image.')
  dst_group.add_argument('--build_channel', type=str, default='',
                         help='Channel of the build of the target image.')
  dst_group.add_argument('--build_version', type=str, default='',
                         help='Channel of the build of the the target image.')

  # Because we archive/call old versions of this script, we can't easily remove
  # command line options, even if we ignore this one now.
  parser.add_argument('--patch_kernel', action='store_true',
                      help='Ignored. Present for compatibility.')

  # Specifying any of the following will cause it to not be cleaned up on exit.
  parser.add_argument('--kern_path', type='path',
                      help='File path for extracting the kernel partition.')
  parser.add_argument('--root_path', type='path',
                      help='File path for extracting the rootfs partition.')
  parser.add_argument('--root_pretruncate_path', type='path',
                      help='File path for extracting the rootfs partition, '
                           'pre-truncation.')
  parser.add_argument('--src_kern_path', type='path',
                      help='File path for extracting the source kernel '
                           'partition.')
  parser.add_argument('--src_root_path', type='path',
                      help='File path for extracting the source root '
                           'partition.')

  opts = parser.parse_args(argv)
  opts.Freeze()

  if not opts.extract and not opts.output:
    parser.error('You must specify an output filename with --output FILENAME')

  return opts


def main(argv):
  opts = ParseArguments(argv)

  return GenerateUpdatePayload(opts)
