#!/usr/bin/python

# 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.

"""Script to generate a zip file of delta-generator and its dependencies."""

import logging.handlers
import optparse
import os
import shutil
import subprocess
import tempfile

# GLOBALS
image_sign_dir = '~/trunk/src/platform/vboot_reference/scripts/image_signing'
BINARY_EXECUTABLES = [
    '/usr/bin/old_bins/cgpt',
    '/usr/bin/delta_generator',
    '/usr/bin/bsdiff',
    '/usr/bin/bspatch',
    ]
EXECUTABLE_FILES = BINARY_EXECUTABLES + [
    '~/trunk/src/scripts/common.sh',
    '/usr/bin/cros_generate_update_payload',
    '~/trunk/src/scripts/chromeos-common.sh',
    os.path.join(image_sign_dir, 'convert_recovery_to_ssd.sh'),
    os.path.join(image_sign_dir, 'common_minimal.sh'),
    ]
# We need directories to be copied recursively to a dest within tempdir
SHELL_LIBRARIES = {'~/trunk/src/scripts/lib/shflags': 'lib/shflags'}


def CopyExecutableFiles(elf_binaries, zip_base):
  """Copy the listed binaries over to the target directory.

  For each binary 'foo' in elf_binaries create:

    zip_base/foo
      Wrapper script to handle dynamic linking when run:

    zip_base/foo.elf
      Originarl binary.

    zip_base/lib/...
      All libraries that foo depends on.

  Args:
    elf_binaries: List of binaries to copy, along with libraries.
    zip_base: Directory into which binaries/libraries are to be placed.
  """
  elf_binaries = [os.path.expanduser(p) for p in elf_binaries]

  cmd = ['/mnt/host/source/chromite/bin/lddtree',
         '--copy-to-tree', zip_base,
         '--copy-non-elfs',
         '--bindir', '/',
         '--libdir', '/lib',
         '--generate-wrappers']
  cmd += elf_binaries

  subprocess.check_call(cmd)


def CopyShellLibraries(shell_libraries, zip_base):
  """Copy shell library directories into the zip_base.

    Args:
      shell_libraries: A dictionary mapping directory_to_copy ->
                                            directory_relative_zip_base.
      zip_base: Target directory to copy into.
  """

  for source_dir, target_dir in shell_libraries.iteritems():
    src = os.path.expanduser(source_dir)
    dest = os.path.join(zip_base, target_dir)
    logging.debug('Copying %s -> %s', src, dest)
    shutil.copytree(src, dest)


def GenerateZipFile(zip_file, zip_base):
  """Create the specified zip file with contents of a directory.

  Args:
    zip_file: name of the zip file.
    zip_base: The directory that we should zip.
  """
  # Make sure the directory for the output file exists.
  zip_output_dir = os.path.dirname(zip_file)
  if not os.path.exists(zip_output_dir):
    os.makedirs(zip_output_dir)

  # Make sure the output zip file doesn't exist, so we start clean.
  if os.path.exists(zip_file):
    os.unlink(zip_file)

  logging.debug('Generating zip file %s with contents from %s', zip_file,
               zip_base)
  current_dir = os.getcwd()
  try:
    os.chdir(zip_base)
    subprocess.check_call(['zip', '-r', '-9', zip_file, '.'])
  finally:
    os.chdir(current_dir)


def main():
  """Main function to start the script"""
  parser = optparse.OptionParser()

  parser.add_option(
      '-d', '--debug', dest='debug', action='store_true',
      default=False, help='Verbose [%default]',)
  parser.add_option(
      '-o', '--output-dir', dest='output_dir',
      default='/tmp/au-generator',
      help='The output location for copying the zipfile [%default]')
  parser.add_option(
      '-z', '--zip-name', dest='zip_name',
      default='au-generator.zip', help='Name of the zip file. [%default]')
  parser.add_option(
      '-k', '--keep-temp', dest='keep_temp', default=False,
      action='store_true', help='Keep the temp files... [%default]',)

  logging_format = '%(asctime)s - %(filename)s - %(levelname)-8s: %(message)s'
  date_format = '%Y/%m/%d %H:%M:%S'
  logging.basicConfig(level=logging.INFO, format=logging_format,
                      datefmt=date_format)

  (options, _) = parser.parse_args()
  if options.debug:
    logging.getLogger().setLevel(logging.DEBUG)

  logging.debug('Options are %s ', options)

  zip_base = None
  try:
    zip_base = tempfile.mkdtemp(suffix='au', prefix='tmp')
    logging.debug('Using tempdir = %s', zip_base)

    CopyExecutableFiles(EXECUTABLE_FILES, zip_base)
    CopyShellLibraries(SHELL_LIBRARIES, zip_base)

    zip_file = os.path.join(options.output_dir, options.zip_name)
    GenerateZipFile(zip_file, zip_base)
    logging.info('Generated %s' % zip_file)

  finally:
    if zip_base and not options.keep_temp:
      shutil.rmtree(zip_base, ignore_errors=True)
      logging.debug('Removed tempdir = %s', zip_base)

if __name__ == '__main__':
  main()
