#!/usr/bin/python

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

"""This module is responsible for generate a stateful update payload."""

import logging
import optparse
import os
import sys
import subprocess
import tempfile

STATEFUL_FILE = 'stateful.tgz'


def GenerateStatefulPayload(image_path, output_directory, logger):
    """Generates a stateful update payload given a full path to an image.

    Args:
      image_path: Full path to the image.
      output_directory: Path to the directory to leave the resulting output.
      logger: logging instance.
    """
    logger.info('Generating stateful update file.')
    from_dir = os.path.dirname(image_path)
    image = os.path.basename(image_path)
    output_gz = os.path.join(output_directory, STATEFUL_FILE)
    # TODO(zbehan): This is only used for mount_gpt_image.sh. That script also
    # needs to move away from src/scripts.
    try:
      crosutils_dir = '%s/src/scripts' % os.environ['CROS_WORKON_SRCROOT']
    except KeyError:
      # Wow, we're outside the chroot. There's no clean way to do this, but we
      # need to find out where sourceroot is.
      # The two places where we may be running is platform/dev/, or /usr/bin/.
      # Coincidentally, both are just a ../../../ away from sourceroot. Other
      # locations for this script will just not work, and long term, we want
      # exactly one anyway. (/usr/bin/)
      self_path = os.path.dirname(sys.argv[0])
      crosutils_dir = os.path.realpath(
          os.path.join(self_path, '../../..', 'src/scripts'))

    # Temporary directories for this function.
    rootfs_dir = tempfile.mkdtemp(suffix='rootfs', prefix='tmp')
    stateful_dir = tempfile.mkdtemp(suffix='stateful', prefix='tmp')

    # Mount the image to pull out the important directories.
    try:
      # Only need stateful partition, but this saves us having to manage our
      # own loopback device.
      subprocess.check_call(['%s/mount_gpt_image.sh' % crosutils_dir,
                             '--from=%s' % from_dir,
                             '--image=%s' % image,
                             '--read_only',
                             '--rootfs_mountpt=%s' % rootfs_dir,
                             '--stateful_mountpt=%s' % stateful_dir,
                            ])
      logger.info('Tarring up /usr/local and /var!')
      subprocess.check_call(['sudo',
                             'tar',
                             '-czf',
                             output_gz,
                             '--directory=%s' % stateful_dir,
                             '--hard-dereference',
                             '--transform=s,^dev_image,dev_image_new,',
                             '--transform=s,^var_overlay,var_new,',
                             'dev_image',
                             'var_overlay',
                            ])
    except:
      logger.error('Failed to create stateful update file')
      raise
    finally:
      # Unmount best effort regardless.
      subprocess.call(['%s/mount_gpt_image.sh' % crosutils_dir,
                       '--unmount',
                       '--rootfs_mountpt=%s' % rootfs_dir,
                       '--stateful_mountpt=%s' % stateful_dir,
                      ])
      # Clean up our directories.
      os.rmdir(rootfs_dir)
      os.rmdir(stateful_dir)

    logger.info('Successfully generated %s' % output_gz)


def main():
  logging.basicConfig(level=logging.INFO)
  logger = logging.getLogger(os.path.basename(__file__))
  parser = optparse.OptionParser()
  parser.add_option('-i', '--image_path',
      help='The image to generate the stateful update for.')
  parser.add_option('-o', '--output_dir',
      help='The path to the directory to output the update file.')
  options, unused_args = parser.parse_args()
  if not options.image_path:
    parser.error('Missing image for stateful payload generator')
  if not options.output_dir:
    parser.error('Missing output directory for the payload generator')

  GenerateStatefulPayload(os.path.abspath(options.image_path),
                          options.output_dir, logger)


if __name__ == '__main__':
  main()
