#!/usr/bin/env python
#
# 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.

"""Creates a tiny self-contained Python executable.

This is similar to "make_par", in a more general and lightweight way.
The generated executable contains only the modules you have explicitly
specified, and can be used to execute them as main. Note you have to include
all dependent modules explicitly - this script won't try to load modules to
solve dependency.

After the PAR file is created, run it with a symlink to the expected command
name or specify the command as first argument to execute.

For examples:

  # Run the program with native name.
  tiny_par -o pygpt -m cros.factory.utils.pygpt
  ./pygpt ...

  # Select using symlinks.
  tiny_par -o tools.par \
      -m cros.factory.utils.pygpt \
      -m cros.factory.tools.image_tool
  ln -s tools.par pygpt
  ln -s tools.par image_tool
  ./pygpt ...
  # Select using explicitly command name.
  ./tools.par pygpt ...
"""

from __future__ import print_function

import argparse
import glob
import logging
import os
import shutil
import tempfile
import zipfile


# A pattern in TEMPLATE to be replaced with real module list.
MODULES_PATTERN = '__MODULES_HERE__'

# The template is a stub to be inserted in the beginning of output PAR file.
TEMPLATE = """#!/bin/sh
EXEC_FILE="$(basename "$0")"
REAL_PATH="$(readlink -f "$0")"
REAL_DIR="$(dirname "${REAL_PATH}")"
COMMANDS=""
MODULES="__MODULES_HERE__"
MODULE=""

find_command() {
  local command="$1" module="" name=""
  COMMANDS=""
  for module in ${MODULES}; do
    name="${module##*.}"
    if [ "${name}" = "${command}" ]; then
      MODULE="${module}"
      return 0
    fi
    COMMANDS="${COMMANDS} ${name}"
  done
  return 1
}

if ! find_command "${EXEC_FILE}"; then
  if find_command "$1"; then
    shift
  else
    echo "ERROR: No ${EXEC_FILE} in ${REAL_PATH}. Available:${COMMANDS}" >&2
    exit 1
  fi
fi

export PYTHONPATH="${PYTHONPATH}:${REAL_PATH}"
export PAR_PATH="${REAL_PATH}"
export PATH="${PATH}:${REAL_DIR}"
exec python -m "${MODULE}" "$@"
exit 1
# Should never reach here. Anything below are reserved for ZIP.
"""


def CollectFiles(pkg_dir, modules, output, init_modules):
  """Collects files needed from modules into given output folder.

  Args:
    pkg_dir: a path to the root of modules.
    modules: a list of string for Python module (a.b.c).
    output: a path to the root of output.
    init_modules: a list of string for __init__ style modules.
  """
  for module in modules:
    src_path = module.replace('.', '/') + '.py'
    par_dir = os.path.dirname(src_path)
    dest_path = output

    # Build directory and init files.
    for entry in par_dir.split('/'):
      dest_path = os.path.join(dest_path, entry)
      if os.path.exists(dest_path):
        continue

      logging.debug('%s => %s (mkdir + init)', src_path, dest_path)
      os.mkdir(dest_path)
      for init in init_modules:
        with open(os.path.join(dest_path, init + '.py'), 'a'):
          pass

    # Copy the real module file.
    logging.debug('%s => %s', src_path, dest_path)
    shutil.copy(os.path.join(pkg_dir, src_path), dest_path)


def BuildPythonZip(py_dir, zip_name='_stage.zip'):
  """Builds a Python zip file from given directory.

  Args:
    py_dir: a path to folder with all Python files available.
    zip_name: the file name to be created.

  Returns:
    A path to the created Zip file (in py_dir).
  """
  targets = glob.glob(os.path.join(py_dir, '*'))
  zip_path = os.path.join(py_dir, zip_name)
  with zipfile.PyZipFile(zip_path, 'w') as par_file:
    for target in targets:
      par_file.writepy(target)
  return zip_path


def main(argv=None):
  parser = argparse.ArgumentParser(
      description=__doc__, formatter_class=argparse.RawDescriptionHelpFormatter)
  parser.add_argument(
      '--output', '-o', default='tinypar.par',
      help='output file. default: %(default)s')
  parser.add_argument(
      '--pkg', '-k', default='.',
      help='path to the Python package folder to find modules.')
  parser.add_argument(
      '-m', '--module', dest='modules', action='append', default=[],
      help='include given module with main (which can be a command).')
  parser.add_argument(
      '--extra_init', default='factory_common',
      help=('extra init-like file to create in each module directory. '
            'default: %(default)s'))
  parser.add_argument(
      '--verbose', '-v', action='count', help='increase output verbosity.')
  # TODO(hungte) Add an option to add extra PATH in invocation.
  # TODO(hungte) Add an option to "add dependency but not as executable".
  # TODO(hungte) Add an option to "add a full directory".
  args = parser.parse_args(argv)
  logging.basicConfig(level=logging.WARNING - 10 * (args.verbose or 0))

  if not args.modules:
    exit('ERROR: Need at least one module (-m).')

  init_modules = ['__init__']
  if args.extra_init:
    init_modules += [args.extra_init]

  tmp_dir = os.path.realpath(tempfile.mkdtemp(prefix='tiny_par.'))
  try:
    CollectFiles(args.pkg, args.modules, tmp_dir, init_modules)
    zip_path = BuildPythonZip(tmp_dir)
    with open(args.output, 'w') as f:
      f.write(TEMPLATE.replace(MODULES_PATTERN, ' '.join(args.modules)))
      with open(zip_path, 'r') as z:
        f.write(z.read())
    os.chmod(args.output, 0o755)
    print('Successfully created PAR executable: %s' % args.output)
  finally:
    shutil.rmtree(tmp_dir)



if __name__ == '__main__':
  main()
