# -*- coding: utf-8 -*-
# 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.

"""Hold the functions that do the real work generating payloads."""

from __future__ import print_function

import base64
import datetime
import json
import os
import shutil
import subprocess
import tempfile
import threading
import time

from collections import deque

from chromite.lib import dlc_lib
from chromite.lib import chroot_util
from chromite.lib import constants
from chromite.lib import cros_build_lib
from chromite.lib import cros_logging as logging
from chromite.lib import image_lib
from chromite.lib import osutils
from chromite.lib import path_util
from chromite.lib import pformat
from chromite.lib.paygen import download_cache
from chromite.lib.paygen import filelib
from chromite.lib.paygen import gspaths
from chromite.lib.paygen import partition_lib
from chromite.lib.paygen import signer_payloads_client
from chromite.lib.paygen import urilib
from chromite.lib.paygen import utils

from chromite.scripts import cros_set_lsb_release


DESCRIPTION_FILE_VERSION = 2

# See class docs for functionality information. Configured to reserve 6GB and
# consider each individual task as consuming 6GB. Therefore we won't start a
# new task unless available memory is about 12GB (including base utilization).
# We set a total max concurrency as a precaution. TODO(crbug.com/1016555)
_mem_semaphore = utils.MemoryConsumptionSemaphore(
    system_available_buffer_bytes=2**31 + 2**32,  # 6 GB
    single_proc_max_bytes=2**31 + 2**32,  # 6 GB
    quiescence_time_seconds=60.0,
    total_max=10,
    unchecked_acquires=4)


class Error(Exception):
  """Base class for payload generation errors."""


class UnexpectedSignerResultsError(Error):
  """This is raised when signer results don't match our expectations."""


class PayloadVerificationError(Error):
  """Raised when the generated payload fails to verify."""


class PaygenPayload(object):
  """Class to manage the process of generating and signing a payload."""

  # 250 GB of cache.
  CACHE_SIZE = 250 * 1024 * 1024 * 1024

  # 10 minutes.
  _SEMAPHORE_TIMEOUT = 10 * 60

  # What keys do we sign payloads with, and what size are they?
  PAYLOAD_SIGNATURE_KEYSETS = ('update_signer',)
  PAYLOAD_SIGNATURE_SIZES_BYTES = (2048 // 8,)  # aka 2048 bits in bytes.

  TEST_IMAGE_NAME = 'chromiumos_test_image.bin'
  RECOVERY_IMAGE_NAME = 'recovery_image.bin'
  BASE_IMAGE_NAME = 'chromiumos_base_image.bin'

  _KERNEL = 'kernel'
  _ROOTFS = 'root'

  def __init__(self,
               payload,
               work_dir,
               sign=False,
               verify=False,
               private_key=None,
               upload=True,
               cache_dir=None):
    """Init for PaygenPayload.

    Args:
      payload: An instance of gspaths.Payload describing the payload to
               generate.
      work_dir: A working directory inside the chroot to put temporary files.
          This can NOT be shared among different runs of PaygenPayload otherwise
          there would be file collisions. Among the things that may go into this
          direcotry are intermediate image files, extracted partitions,
          different logs and metadata files, payload and metadata hashes along
          with their signatures, the payload itself, postinstall config file,
          intermediate files that is generated by the signer, etc.
      sign: Boolean saying if the payload should be signed (normally, you do).
      verify: whether the payload should be verified after being generated
      private_key: If passed, the payload will be signed with that private key.
                   If also verify is True, the public key is extracted from the
                   private key and is used for verification.
      upload: Boolean saying if payload generation results should be uploaded.
      cache_dir: If passed, override the default cache dir (useful on bots).
    """
    self.payload = payload
    self.work_dir = work_dir
    self._verify = verify
    self._private_key = private_key
    self._public_key = None
    self._upload = upload

    self.src_image_file = os.path.join(work_dir, 'src_image.bin')
    self.tgt_image_file = os.path.join(work_dir, 'tgt_image.bin')

    self.partition_names = None
    self.tgt_partitions = None
    self.src_partitions = None

    self._appid = ''

    self.payload_file = os.path.join(work_dir, 'delta.bin')
    self.log_file = os.path.join(work_dir, 'delta.log')
    self.description_file = os.path.join(work_dir, 'delta.json')
    self.metadata_size = 0
    self.metadata_hash_file = os.path.join(work_dir, 'metadata_hash')
    self.payload_hash_file = os.path.join(work_dir, 'payload_hash')

    self._postinst_config_file = os.path.join(work_dir, 'postinst_config')

    # How big will the signatures be.
    self._signature_sizes = [str(size) for size in
                             self.PAYLOAD_SIGNATURE_SIZES_BYTES]
    self.signer = None
    if sign:
      self._SetupSigner(payload.build)

    # This cache dir will be shared with other processes, but we need our own
    # instance of the cache manager to properly coordinate.
    cache_dir = cache_dir or self._FindCacheDir()
    self._cache = download_cache.DownloadCache(
        cache_dir, cache_size=PaygenPayload.CACHE_SIZE)

  def _MetadataUri(self, uri):
    """Given a payload uri, find the uri for the metadata signature."""
    return uri + '.metadata-signature'

  def _LogsUri(self, uri):
    """Given a payload uri, find the uri for the logs."""
    return uri + '.log'

  def _JsonUri(self, uri):
    """Given a payload uri, find the uri for the json payload description."""
    return uri + '.json'

  def _FindCacheDir(self):
    """Helper for deciding what cache directory to use.

    Returns:
      Returns a directory suitable for use with a DownloadCache.
    """
    return os.path.join(path_util.GetCacheDir(), 'paygen_cache')

  def _SetupSigner(self, payload_build):
    """Sets up the signer based on which bucket the payload is supposed to go.

    Args:
      payload_build: The build defined for the payload.
    """
    self.signed_payload_file = self.payload_file + '.signed'
    self.metadata_signature_file = self._MetadataUri(self.signed_payload_file)

    if (payload_build and
        payload_build.bucket == gspaths.ChromeosReleases.BUCKET):
      # We are using the official buckets, so sign it with official signers.
      self.signer = signer_payloads_client.SignerPayloadsClientGoogleStorage(
          payload_build, self.work_dir)
      # We set the private key to None so we don't accidentally use a valid
      # passed private key to verify the image.
      self._private_key = None
    else:
      # Otherwise use a private key for signing and verifying the payload. If
      # no private_key was provided, use a test key.
      if not self._private_key:
        self._private_key = os.path.join(constants.CHROMITE_DIR, 'ssh_keys',
                                         'testing_rsa')
      self.signer = signer_payloads_client.UnofficialSignerPayloadsClient(
          self._private_key, self.work_dir)

    if self._private_key and self.signer:
      self._public_key = os.path.join(self.work_dir, 'public_key.pem')
      self.signer.ExtractPublicKey(self._public_key)

  def _GetDlcImageParams(self, tgt_image, src_image=None):
    """Returns parameters related to target and source DLC images.

    Args:
      tgt_image: The target image.
      src_image: The source image.

    Returns:
      A tuple of three parameters that was discovered from the image: The DLC
      ID, The DLC package and its release AppID.
    """

    def _GetImageParams(image):
      """Returns the parameters of a single DLC image.

      Args:
        image: The input image.

      Returns:
        Same values as _GetDlcImageParams()
      """
      mount_point = os.path.join(self.work_dir, 'mount-point')
      osutils.MountDir(image, mount_point, mount_opts=('ro',))
      try:
        lsb_release = utils.ReadLsbRelease(mount_point)
      finally:
        osutils.UmountDir(mount_point)

      dlc_id = lsb_release[dlc_lib.DLC_ID_KEY]
      dlc_package = lsb_release[dlc_lib.DLC_PACKAGE_KEY]
      appid = lsb_release[dlc_lib.DLC_APPID_KEY]

      if gspaths.IsDLCImage(image):
        if dlc_id != image.dlc_id:
          raise Error('The DLC ID (%s) inferred from the file path does not '
                      'match the one (%s) from the lsb-release.' %
                      (image.dlc_id, dlc_id))
        if dlc_package != image.dlc_package:
          raise Error('The DLC package (%s) inferred from the file path '
                      'does not match the one (%s) from the lsb-release.' %
                      (image.dlc_package, dlc_package))

      return dlc_id, dlc_package, appid

    tgt_dlc_id, tgt_dlc_package, tgt_appid = _GetImageParams(tgt_image)
    if src_image:
      src_dlc_id, src_dlc_package, src_appid = _GetImageParams(src_image)
      if tgt_dlc_id != src_dlc_id:
        raise Error('Source (%s) and target (%s) DLC IDs do not match.' %
                    (src_dlc_id, tgt_dlc_id))
      if tgt_dlc_package != src_dlc_package:
        raise Error('Source (%s) and target (%s) DLC packages do not match.'
                    % (src_dlc_package, tgt_dlc_package))
      if tgt_appid != src_appid:
        logging.warning('Source (%s) and target (%s) App IDs do not match.',
                        src_appid, tgt_appid)

    return tgt_dlc_id, tgt_dlc_package, tgt_appid

  def _GetPlatformImageParams(self, image):
    """Returns parameters related to target or source platform images.

    Since this function is mounting a GPT image, if the mount (for reasons like
    a bug, etc), changes the bits on the image, then the image cannot be trusted
    after this call.

    Args:
      image: The input image.

    Returns:
      The release APPID of the image.
    """
    # Mount the ROOT-A partition of the image. The reason we don't mount the
    # extracted partition directly is that if by mistake/bug the mount changes
    # the bits on the partition, then we will create a payload for a changed
    # partition which is not equivalent to the original partition. So just mount
    # the partition of the GPT image and even if it changes, then who cares.
    #
    # TODO(crbug.com/925203): Replace this with image_lib.LoopbackPartition()
    # once the mentioned bug is resolved.
    with osutils.TempDir(base_dir=self.work_dir) as mount_point:
      with image_lib.LoopbackPartitions(image, destination=mount_point,
                                        part_ids=(constants.PART_ROOT_A,)):
        sysroot_dir = os.path.join(mount_point,
                                   'dir-%s' % constants.PART_ROOT_A)
        lsb_release = utils.ReadLsbRelease(sysroot_dir)
        app_id = lsb_release.get(cros_set_lsb_release.LSB_KEY_APPID_RELEASE)
        if app_id is None:
          board = lsb_release.get(cros_set_lsb_release.LSB_KEY_APPID_BOARD)
          logging.error('APPID is missing in board %s. In some boards that do '
                        'not do auto updates, like amd64-generic, this is '
                        'expected, otherwise this is an error.', board)
        return app_id

  def _PreparePartitions(self):
    """Prepares parameters related to partitions of the given image.

    This function basically distinguishes between normal platform images and DLC
    images and creates and checks parameters necessary for each of them.
    """
    tgt_image_type = partition_lib.LookupImageType(self.tgt_image_file)
    if self.payload.src_image:
      src_image_type = partition_lib.LookupImageType(self.src_image_file)
      if (tgt_image_type != src_image_type and
          partition_lib.CROS_IMAGE in (tgt_image_type, src_image_type)):
        raise Error('Source (%s) and target (%s) images have different types.' %
                    (src_image_type, tgt_image_type))

    if tgt_image_type == partition_lib.DLC_IMAGE:
      logging.info('Detected a DLC image.')

      # DLC module image has only one partition which is the image itself.
      dlc_id, dlc_package, self._appid = self._GetDlcImageParams(
          self.tgt_image_file,
          src_image=self.src_image_file if self.payload.src_image else None)
      self.partition_names = ('dlc/%s/%s' % (dlc_id, dlc_package),)
      self.tgt_partitions = (self.tgt_image_file,)
      self.src_partitions = (self.src_image_file,)

    elif tgt_image_type == partition_lib.CROS_IMAGE:
      logging.info('Detected a Chromium OS image.')

      self.partition_names = (self._ROOTFS, self._KERNEL)
      self.tgt_partitions = tuple(os.path.join(self.work_dir,
                                               'tgt_%s.bin' % name)
                                  for name in self.partition_names)
      self.src_partitions = tuple(os.path.join(self.work_dir,
                                               'src_%s.bin' % name)
                                  for name in self.partition_names)

      partition_lib.ExtractRoot(self.tgt_image_file, self.tgt_partitions[0])
      partition_lib.ExtractKernel(self.tgt_image_file, self.tgt_partitions[1])
      if self.payload.src_image:
        partition_lib.ExtractRoot(self.src_image_file, self.src_partitions[0])
        partition_lib.ExtractKernel(self.src_image_file, self.src_partitions[1])

      # This step should be done after extracting partitions, look at the
      # _GetPlatformImageParams() documentation for more info.
      self._appid = self._GetPlatformImageParams(self.tgt_image_file)
      # Reset the target image file path so no one uses it later.
      self.tgt_image_file = None

      # Makes sure we have generated postinstall config for major version 2 and
      # platform image.
      self._GeneratePostinstConfig(True)
    else:
      raise Error('Invalid image type %s' % tgt_image_type)

  def _RunGeneratorCmd(self, cmd, squawk_wrap=False):
    """Wrapper for run in chroot.

    Run the given command inside the chroot. It will automatically log the
    command output. Note that the command's stdout and stderr are combined into
    a single string.

    For context on why this is so complex see: crbug.com/1035799

    Args:
      cmd: Program and argument list in a list. ['delta_generator', '--help']
      squawk_wrap: Optionally run the cros_build_lib command in a thread to
                   avoid being killed by the ProcessSilentTimeout during quiet
                   periods of delta_gen.

    Raises:
      cros_build_lib.RunCommandError if the command exited without success.
    """

    response_queue = deque()

    # The later thread's start() function.
    def _inner_run(cmd, response_queue):
      try:
        # Run the command.
        result = cros_build_lib.run(
            cmd,
            stdout=True,
            enter_chroot=True,
            stderr=subprocess.STDOUT)
        response_queue.append(result)
      except cros_build_lib.RunCommandError as e:
        response_queue.append(e)

    if squawk_wrap:
      inner_run_thread = threading.Thread(
          target=_inner_run, name='delta_generator_run_wrapper',
          args=(cmd, response_queue))
      inner_run_thread.setDaemon(True)
      inner_run_thread.start()
      # Wait for the inner run thread to finish, waking up each second.
      i = 1
      while inner_run_thread.isAlive():
        i += 1
        time.sleep(1)
        # Only report once an hour, otherwise we'd be too noisy.
        if i % 3600 == 0:
          logging.info('Placating ProcessSilentTimeout...')
    else:
      _inner_run(cmd, response_queue)

    try:
      result = response_queue.pop()
      if isinstance(result, cros_build_lib.RunCommandError):
        # Dump error output and re-raise the exception.
        logging.error('Nonzero exit code (%d), dumping command output:\n%s',
                      result.result.returncode, result.result.output)
        raise result
      elif isinstance(result, cros_build_lib.CommandResult):
        self._StoreLog('Output of command: ' + result.cmdstr)
        self._StoreLog(result.output.decode('utf-8', 'replace'))
      else:
        raise cros_build_lib.RunCommandError(
            'return type from _inner_run unknown')
    except IndexError:
      raise cros_build_lib.RunCommandError(
          'delta_generator_run_wrapper did not return a value')



  @staticmethod
  def _BuildArg(flag, dict_obj, key, default=None):
    """Returns a command-line argument iff its value is present in a dictionary.

    Args:
      flag: the flag name to use with the argument value, e.g. --foo; if None
            or an empty string, no flag will be used
      dict_obj: a dictionary mapping possible keys to values
      key: the key of interest; e.g. 'foo'
      default: a default value to use if key is not in dict_obj (optional)

    Returns:
      If dict_obj[key] contains a non-False value or default is non-False,
      returns a string representing the flag and value arguments
      (e.g. '--foo=bar')
    """
    val = dict_obj.get(key) or default
    return '%s=%s' % (flag, str(val))


  def _PrepareImage(self, image, image_file):
    """Download an prepare an image for delta generation.

    Preparation includes downloading, extracting and converting the image into
    an on-disk format, as necessary.

    Args:
      image: an object representing the image we're processing, either
             UnsignedImageArchive or Image type from gspaths module.
      image_file: file into which the prepared image should be copied.
    """

    logging.info('Preparing image from %s as %s', image.uri, image_file)

    # Figure out what we're downloading and how to handle it.
    image_handling_by_type = {
        'signed': (None, True),
        'test': (self.TEST_IMAGE_NAME, False),
        'recovery': (self.RECOVERY_IMAGE_NAME, True),
        'base': (self.BASE_IMAGE_NAME, True),
    }
    if gspaths.IsImage(image):
      # No need to extract.
      extract_file = None
    elif gspaths.IsUnsignedImageArchive(image):
      extract_file, _ = image_handling_by_type[image.get('image_type',
                                                         'signed')]
    else:
      raise Error('Unknown image type %s' % type(image))

    # Are we donwloading an archive that contains the image?
    if extract_file:
      # Archive will be downloaded to a temporary location.
      with tempfile.NamedTemporaryFile(
          prefix='image-archive-', suffix='.tar.xz', dir=self.work_dir,
          delete=False) as temp_file:
        download_file = temp_file.name
    else:
      download_file = image_file

    # Download the image file or archive. If it was just a local file, ignore
    # caching and do a simple copy. TODO(crbug.com/926034): Add a caching
    # mechanism for local files.
    if urilib.GetUriType(image.uri) == urilib.TYPE_LOCAL:
      filelib.Copy(image.uri, download_file)
    else:
      self._cache.GetFileCopy(image.uri, download_file)

    # If we downloaded an archive, extract the image file from it.
    if extract_file:
      cmd = ['tar', '-xJf', download_file, extract_file]
      cros_build_lib.run(cmd, cwd=self.work_dir)

      # Rename it into the desired image name.
      shutil.move(os.path.join(self.work_dir, extract_file), image_file)

      # It should be safe to delete the archive at this point.
      # TODO(crbug/1016555): consider removing the logging once resolved.
      logging.info('Removing %s', download_file)
      os.remove(download_file)

  def _GeneratePostinstConfig(self, run_postinst):
    """Generates the postinstall config file

    This file is used in update engine's major version 2.

    Args:
      run_postinst: Whether the updater should run postinst or not.
    """
    # In major version 2 we need to explicity mark the postinst on the root
    # partition to run.
    osutils.WriteFile(self._postinst_config_file,
                      'RUN_POSTINSTALL_root=%s\n' %
                      ('true' if run_postinst else 'false'))

  def _GenerateUnsignedPayload(self):
    """Generate the unsigned delta into self.payload_file."""
    # Note that the command run here requires sudo access.
    logging.info('Generating unsigned payload as %s', self.payload_file)

    cmd = ['delta_generator',
           '--major_version=2',
           '--out_file=' + path_util.ToChrootPath(self.payload_file),
           # Target image args: (The order of partitions are important.)
           '--partition_names=' + ':'.join(self.partition_names),
           '--new_partitions=' +
           ':'.join(path_util.ToChrootPath(x) for x in self.tgt_partitions)]

    if os.path.exists(self._postinst_config_file):
      cmd += ['--new_postinstall_config_file=' +
              path_util.ToChrootPath(self._postinst_config_file)]

    if self.payload.src_image:
      cmd += ['--old_partitions=' +
              ':'.join(path_util.ToChrootPath(x) for x in self.src_partitions)]

    # This can take a very long time with no output, so wrap the call.
    self._RunGeneratorCmd(cmd, squawk_wrap=True)

  def _GenerateHashes(self):
    """Generate a payload hash and a metadata hash.

    Works from an unsigned update payload.

    Returns:
      Tuple of (payload_hash, metadata_hash) as bytes.
    """
    logging.info('Calculating hashes on %s.', self.payload_file)

    cmd = ['delta_generator',
           '--in_file=' + path_util.ToChrootPath(self.payload_file),
           '--signature_size=' + ':'.join(self._signature_sizes),
           '--out_hash_file=' +
           path_util.ToChrootPath(self.payload_hash_file),
           '--out_metadata_hash_file=' +
           path_util.ToChrootPath(self.metadata_hash_file)]

    self._RunGeneratorCmd(cmd)

    return (osutils.ReadFile(self.payload_hash_file, mode='rb'),
            osutils.ReadFile(self.metadata_hash_file, mode='rb'))

  def _GenerateSignerResultsError(self, format_str, *args):
    """Helper for reporting errors with signer results."""
    msg = format_str % args
    logging.error(msg)
    raise UnexpectedSignerResultsError(msg)

  def _SignHashes(self, hashes):
    """Get the signer to sign the hashes with the update payload key via GS.

    May sign each hash with more than one key, based on how many keysets are
    required.

    Args:
      hashes: List of hashes (as bytes) to be signed.

    Returns:
      List of lists which contain each signed hash (as bytes).
      [[hash_1_sig_1, hash_1_sig_2], [hash_2_sig_1, hash_2_sig_2]]
    """
    logging.info('Signing payload hashes with %s.',
                 ', '.join(self.PAYLOAD_SIGNATURE_KEYSETS))

    # Results look like:
    #  [[hash_1_sig_1, hash_1_sig_2], [hash_2_sig_1, hash_2_sig_2]]
    hashes_sigs = self.signer.GetHashSignatures(
        hashes,
        keysets=self.PAYLOAD_SIGNATURE_KEYSETS)

    if hashes_sigs is None:
      self._GenerateSignerResultsError('Signing of hashes failed')
    if len(hashes_sigs) != len(hashes):
      self._GenerateSignerResultsError(
          'Count of hashes signed (%d) != Count of hashes (%d).',
          len(hashes_sigs),
          len(hashes))

    # Make sure that the results we get back the expected number of signatures.
    for hash_sigs in hashes_sigs:
      # Make sure each hash has the right number of signatures.
      if len(hash_sigs) != len(self.PAYLOAD_SIGNATURE_SIZES_BYTES):
        self._GenerateSignerResultsError(
            'Signature count (%d) != Expected signature count (%d)',
            len(hash_sigs),
            len(self.PAYLOAD_SIGNATURE_SIZES_BYTES))

      # Make sure each hash signature is the expected size.
      for sig, sig_size in zip(hash_sigs, self.PAYLOAD_SIGNATURE_SIZES_BYTES):
        if len(sig) != sig_size:
          self._GenerateSignerResultsError(
              'Signature size (%d) != expected size(%d)',
              len(sig),
              sig_size)

    return hashes_sigs

  def _WriteSignaturesToFile(self, signatures):
    """Write each signature into a temp file in the chroot.

    Args:
      signatures: A list of signatures as bytes to write into file.

    Returns:
      The list of files in the chroot with the same order as signatures.
    """
    file_paths = []
    for signature in signatures:
      path = tempfile.NamedTemporaryFile(dir=self.work_dir, delete=False).name
      osutils.WriteFile(path, signature, mode='wb')
      file_paths.append(path_util.ToChrootPath(path))

    return file_paths

  def _InsertSignaturesIntoPayload(self, payload_signatures,
                                   metadata_signatures):
    """Put payload and metadta signatures into the payload we sign.

    Args:
      payload_signatures: List of signatures as bytes for the payload.
      metadata_signatures: List of signatures as bytes for the metadata.
    """
    logging.info('Inserting payload and metadata signatures into %s.',
                 self.signed_payload_file)

    payload_signature_file_names = self._WriteSignaturesToFile(
        payload_signatures)
    metadata_signature_file_names = self._WriteSignaturesToFile(
        metadata_signatures)

    cmd = ['delta_generator',
           '--in_file=' + path_util.ToChrootPath(self.payload_file),
           '--signature_size=' + ':'.join(self._signature_sizes),
           '--payload_signature_file=' + ':'.join(payload_signature_file_names),
           '--metadata_signature_file=' +
           ':'.join(metadata_signature_file_names),
           '--out_file=' + path_util.ToChrootPath(self.signed_payload_file)]

    self._RunGeneratorCmd(cmd)

  def _StoreMetadataSignatures(self, signatures):
    """Store metadata signatures related to the payload.

    Our current format for saving metadata signatures only supports a single
    signature at this time.

    Args:
      signatures: A list of metadata signatures in binary string format.
    """
    if len(signatures) != 1:
      self._GenerateSignerResultsError(
          'Received %d metadata signatures, only a single signature supported.',
          len(signatures))

    logging.info('Saving metadata signatures in %s.',
                 self.metadata_signature_file)

    encoded_signature = base64.b64encode(signatures[0])

    with open(self.metadata_signature_file, 'w+b') as f:
      f.write(encoded_signature)

  def GetPayloadPropertiesMap(self, payload_path):
    """Returns the payload's properties attributes in dictionary.

    The payload description contains a dictionary of key/values describing the
    characteristics of the payload. Look at
    update_engine/payload_generator/payload_properties.cc for the basic
    description of these values.

    In addition we add the following three keys to description file:

    "appid": The APP ID associated with this payload.
    "public_key": The public key the payload was signed with.

    Args:
      payload_path: The path to the payload file.

    Returns:
      A map of payload properties that can be directly used to create the
      payload.json file.
    """
    try:
      payload_path = path_util.ToChrootPath(payload_path)
    except ValueError:
      # Copy the payload inside the chroot and try with that path instead.
      logging.info('The payload is not in the chroot. We will copy it there in '
                   'order to get its properties.')
      copied_payload = os.path.join(self.work_dir, 'copied-payload.bin')
      shutil.copyfile(payload_path, copied_payload)
      payload_path = path_util.ToChrootPath(copied_payload)

    props_file = os.path.join(self.work_dir, 'properties.json')
    cmd = ['delta_generator',
           '--in_file=' + payload_path,
           '--properties_file=' + path_util.ToChrootPath(props_file),
           '--properties_format=json']
    self._RunGeneratorCmd(cmd)
    props_map = json.load(open(props_file))

    # delta_generator assigns empty string for signatures when the payload is
    # not signed. Replace it with 'None' so the json.dumps() writes 'null' as
    # the value to be consistent with the current scheme and not break GE.
    key = 'metadata_signature'
    if not props_map[key]:
      props_map[key] = None

    props_map['appid'] = self._appid

    if self.payload.tgt_image.build:
      props_map['target_version'] = self.payload.tgt_image.build.version
    else:
      props_map['target_version'] = '99999.0.0'

    if self.payload.src_image:
      if self.payload.src_image.build:
        props_map['source_version'] = self.payload.src_image.build.version
      else:
        props_map['source_version'] = ''


    # Add the public key if it exists.
    if self._public_key:
      props_map['public_key'] = base64.b64encode(
          osutils.ReadFile(self._public_key, mode='rb')).decode('utf-8')

    # We need the metadata size later for payload verification. Just grab it
    # from the properties file.
    self.metadata_size = props_map['metadata_size']

    return props_map

  def _StorePayloadJson(self, metadata_signatures):
    """Generate the payload description json file.

    Args:
      metadata_signatures: A list of signatures in binary string format.
    """
    # Decide if we use the signed or unsigned payload file.
    payload_file = self.payload_file
    if self.signer:
      payload_file = self.signed_payload_file

    # Currently we have no way of getting the appid from the payload itself. So
    # just put what we got from the image itself (if any).
    props_map = self.GetPayloadPropertiesMap(payload_file)

    # Check that the calculated metadata signature is the same as the one on the
    # payload.
    if metadata_signatures:
      if len(metadata_signatures) != 1:
        self._GenerateSignerResultsError(
            'Received %d metadata signatures, only one supported.',
            len(metadata_signatures))
      metadata_signature = base64.b64encode(
          metadata_signatures[0]).decode('utf-8')
      if metadata_signature != props_map['metadata_signature']:
        raise Error('Calculated metadata signature (%s) and the signature in'
                    ' the payload (%s) do not match.' %
                    (metadata_signature, props_map['metadata_signature']))

    # Convert to Json & write out the results.
    pformat.json(props_map, fp=self.description_file, compact=True)

  def _StoreLog(self, log):
    """Store any log related to the payload.

    Write out the log to a known file name. Mostly in its own function
    to simplify unittest mocks.

    Args:
      log: The delta logs as a single string.
    """
    try:
      osutils.WriteFile(self.log_file, log, mode='a')
    except TypeError as e:
      logging.error('crbug.com/1023497 osutils.WriteFile failed: %s', e)
      logging.error('log (type %s): %r', type(log), log)
      flat = cros_build_lib.iflatten_instance(log)
      logging.error('flattened: %r', flat)
      logging.error('expanded: %r', list(flat))

  def _SignPayload(self):
    """Wrap all the steps for signing an existing payload.

    Returns:
      List of payload signatures, List of metadata signatures.
    """
    # Create hashes to sign or even if signing not needed.  TODO(ahassani): In
    # practice we don't need to generate hashes if we are not signing, so when
    # devserver stopped depending on cros_generate_update_payload. this can be
    # reverted.
    payload_hash, metadata_hash = self._GenerateHashes()

    if not self.signer:
      return (None, None)

    # Sign them.
    # pylint: disable=unpacking-non-sequence
    payload_signatures, metadata_signatures = self._SignHashes(
        [payload_hash, metadata_hash])
    # pylint: enable=unpacking-non-sequence

    # Insert payload and metadata signature(s).
    self._InsertSignaturesIntoPayload(payload_signatures, metadata_signatures)

    # Store metadata signature(s).
    self._StoreMetadataSignatures(metadata_signatures)

    return (payload_signatures, metadata_signatures)

  def _Create(self):
    """Create a given payload, if it doesn't already exist."""

    logging.info('Generating %s payload %s',
                 'delta' if self.payload.src_image else 'full', self.payload)

    # TODO(lamontjones): Trial test of wrapping the downloads in the semaphore
    # in addition to the actual generation of the unsigned payload.  See if the
    # running of several gsutil cp commands in parallel is increasing the
    # likelihood of EAGAIN from spawning a thread.  See crbug.com/1016555
    #
    # Run delta_generator for the purpose of generating an unsigned payload with
    # considerations for available memory. This is an adaption of the previous
    # version which used a simple semaphore. This was highly limiting because
    # while delta_generator is parallel there are single threaded portions
    # of it that were taking a very long time (i.e. long poles).
    #
    # Sometimes if a process cannot acquire the lock for a long
    # period of time, the builder kills the process for not outputting any
    # logs. So here we try to acquire the lock with a timeout of ten minutes in
    # a loop and log some output so not to be killed by the builder.
    while True:
      acq_result = _mem_semaphore.acquire(timeout=self._SEMAPHORE_TIMEOUT)
      if acq_result.result:
        logging.info('Acquired lock (reason: %s)', acq_result.reason)
        break
      else:
        logging.info('Failed to acquire the lock in 10 minutes (reason: %s)'
                     ', trying again ...', acq_result.reason)
    try:
      # Time the actual paygen operation started.
      start_time = datetime.datetime.now()

      # Fetch and prepare the tgt image.
      self._PrepareImage(self.payload.tgt_image, self.tgt_image_file)

      # Fetch and prepare the src image.
      if self.payload.src_image:
        self._PrepareImage(self.payload.src_image, self.src_image_file)

      # Setup parameters about the payload like whether it is a DLC or not. Or
      # parameters like the APPID, etc.
      self._PreparePartitions()

      # Generate the unsigned payload.
      self._GenerateUnsignedPayload()
    finally:
      _mem_semaphore.release()
      # Time the actual paygen operation ended.
      end_time = datetime.datetime.now()
      logging.info('* Finished payload generation in %s', end_time - start_time)

    # Sign the payload, if needed.
    _, metadata_signatures = self._SignPayload()

    # Store hash and signatures json.
    self._StorePayloadJson(metadata_signatures)

  def _VerifyPayload(self):
    """Checks the integrity of the generated payload.

    Raises:
      PayloadVerificationError when the payload fails to verify.
    """
    if self.signer:
      payload_file_name = self.signed_payload_file
      metadata_sig_file_name = self.metadata_signature_file
    else:
      payload_file_name = self.payload_file
      metadata_sig_file_name = None

    is_delta = bool(self.payload.src_image)

    logging.info('Applying %s payload and verifying result',
                 'delta' if is_delta else 'full')

    # This command checks both the payload integrity and applies the payload
    # to source and target partitions.
    cmd = ['check_update_payload', path_util.ToChrootPath(payload_file_name),
           '--check', '--type', 'delta' if is_delta else 'full',
           '--disabled_tests', 'move-same-src-dst-block',
           '--part_names']
    cmd.extend(self.partition_names)
    cmd += ['--dst_part_paths']
    cmd.extend(path_util.ToChrootPath(x) for x in self.tgt_partitions)
    if metadata_sig_file_name:
      cmd += ['--meta-sig', path_util.ToChrootPath(metadata_sig_file_name)]

    cmd += ['--metadata-size', str(self.metadata_size)]

    if is_delta:
      cmd += ['--src_part_paths']
      cmd.extend(path_util.ToChrootPath(x) for x in self.src_partitions)

    # We signed it with the private key, now verify it with the public key.
    if self._public_key:
      cmd += ['--key', path_util.ToChrootPath(self._public_key)]

    self._RunGeneratorCmd(cmd)

  def _UploadResults(self):
    """Copy the payload generation results to the specified destination."""

    logging.info('Uploading payload to %s.', self.payload.uri)

    # Deliver the payload to the final location.
    if self.signer:
      urilib.Copy(self.signed_payload_file, self.payload.uri)
    else:
      urilib.Copy(self.payload_file, self.payload.uri)

    # Upload payload related artifacts.
    urilib.Copy(self.log_file, self._LogsUri(self.payload.uri))
    urilib.Copy(self.description_file, self._JsonUri(self.payload.uri))

  def Run(self):
    """Create, verify and upload the results.

    Returns:
        A string uri to payload, if uploaded, otherwise None.
    """
    ret_uri = None
    logging.info('* Starting payload generation')
    start_time = datetime.datetime.now()

    self._Create()
    if self._verify:
      self._VerifyPayload()
    if self._upload:
      self._UploadResults()
      ret_uri = self.payload.uri

    end_time = datetime.datetime.now()
    logging.info('* Total elapsed payload generation in %s',
                 end_time - start_time)
    return ret_uri


def CreateAndUploadPayload(payload, sign=True, verify=True):
  """Helper to create a PaygenPayloadLib instance and use it.

  Mainly can be used as a single function to help with parallelism.

  Args:
    payload: An instance of gspaths.Payload describing the payload to generate.
    sign: Boolean saying if the payload should be signed (normally, you do).
    verify: whether the payload should be verified (default: True)
  """
  # We need to create a temp directory inside the chroot so be able to access
  # from both inside and outside the chroot.
  with chroot_util.TempDirInChroot() as work_dir:
    PaygenPayload(payload, work_dir, sign=sign, verify=verify).Run()


def GenerateUpdatePayload(tgt_image, payload, src_image=None, work_dir=None,
                          private_key=None, check=None):
  """Generates output payload and verifies its integrity if needed.

  Args:
    tgt_image: The path (or uri) to the image.
    payload: The path (or uri) to the output payload
    src_image: The path (or uri) to the source image. If passed, a delta payload
        is generated.
    work_dir: A working directory inside the chroot. The None, caller has the
        responsibility to cleanup this directory after this function returns.
    private_key: The private key to sign the payload.
    check: If True, it will check the integrity of the generated payload.
  """
  if path_util.DetermineCheckout().type != path_util.CHECKOUT_TYPE_REPO:
    raise Error('Need a chromeos checkout to generate payloads.')

  tgt_image = gspaths.Image(uri=tgt_image)
  src_image = gspaths.Image(uri=src_image) if src_image else None
  payload = gspaths.Payload(tgt_image=tgt_image, src_image=src_image,
                            uri=payload)
  with chroot_util.TempDirInChroot() as temp_dir:
    work_dir = work_dir if work_dir is not None else temp_dir
    paygen = PaygenPayload(payload, work_dir, sign=private_key is not None,
                           verify=check, private_key=private_key)
    paygen.Run()


def GenerateUpdatePayloadPropertiesFile(payload, output=None):
  """Generates the update payload's properties file.

  Args:
    payload: The path to the input payload.
    output: The path to the output properties json file. If None, the file will
        be placed by appending '.json' to the payload file itself.
  """
  if not output:
    output = payload + '.json'

  with chroot_util.TempDirInChroot() as work_dir:
    paygen = PaygenPayload(None, work_dir)
    properties_map = paygen.GetPayloadPropertiesMap(payload)
    pformat.json(properties_map, fp=output, compact=True)
