#!/usr/bin/env python
# Copyright 2017 - The Android Open Source Project
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""A utility to build and pack gsi_util."""

import argparse
from collections import namedtuple
import errno
import logging
import os
import shutil
import sys
import zipfile

from gsi_util.utils.cmd_utils import run_command

_MAKE_MODULE_NAME = 'gsi_util'

RequiredItem = namedtuple('RequiredItem', 'dest src')

# The list of dependency modules
# Format in (dest, src in host out)
REQUIRED_ITEMS = [
    # named as 'gsi_util.bin' to avoid conflict with the folder 'gsi_util'
    RequiredItem('gsi_util.bin', 'bin/gsi_util'),
    RequiredItem('bin/checkvintf', 'bin/checkvintf'),
    RequiredItem('lib64/libbase.so', 'lib64/libbase.so'),
    RequiredItem('lib64/liblog.so', 'lib64/liblog.so'),
    RequiredItem('bin/simg2img', 'bin/simg2img'),
    RequiredItem('lib64/libc++.so', 'lib64/libc++.so'),
]  # pyformat: disable

# Files to be included to zip file additionally
INCLUDE_FILES = [
    'README.md']  # pyformat: disable


def _check_android_env():
  if not os.environ.get('ANDROID_BUILD_TOP'):
    raise EnvironmentError('Need \'lunch\'.')


def _switch_to_prog_dir():
  prog = sys.argv[0]
  abspath = os.path.abspath(prog)
  dirname = os.path.dirname(abspath)
  os.chdir(dirname)


def _make_all():
  logging.info('Make %s...', _MAKE_MODULE_NAME)

  build_top = os.environ['ANDROID_BUILD_TOP']
  run_command(['make', '-j', _MAKE_MODULE_NAME], cwd=build_top)


def _create_dirs_and_copy_file(dest, src):
  dir_path = os.path.dirname(dest)
  try:
    if dir_path != '':
      os.makedirs(dir_path)
  except OSError as exc:
    if exc.errno != errno.EEXIST:
      raise
  logging.debug('copy(): %s %s', src, dest)
  shutil.copy(src, dest)


def _copy_deps():
  logging.info('Copy depend files...')
  host_out = os.environ['ANDROID_HOST_OUT']
  logging.debug('  ANDROID_HOST_OUT=%s', host_out)

  for item in REQUIRED_ITEMS:
    print 'Copy {}...'.format(item.dest)
    full_src = os.path.join(host_out, item.src)
    _create_dirs_and_copy_file(item.dest, full_src)


def _build_zipfile(filename):
  print 'Archive to {}...'.format(filename)
  with zipfile.ZipFile(filename, mode='w') as zf:
    for f in INCLUDE_FILES:
      print 'Add {}'.format(f)
      zf.write(f)
    for f in REQUIRED_ITEMS:
      print 'Add {}'.format(f[0])
      zf.write(f[0])


def do_setup_env(args):
  _check_android_env()
  _make_all()
  _switch_to_prog_dir()
  _copy_deps()


def do_list_deps(args):
  print 'Depend files (zip <== host out):'
  for item in REQUIRED_ITEMS:
    print '  {:20} <== {}'.format(item.dest, item.src)
  print 'Other include files:'
  for item in INCLUDE_FILES:
    print '  {}'.format(item)


def do_build(args):
  _check_android_env()
  _make_all()
  _switch_to_prog_dir()
  _copy_deps()
  _build_zipfile(args.output)


def main(argv):

  parser = argparse.ArgumentParser()
  subparsers = parser.add_subparsers(title='COMMAND')

  # Command 'setup_env'
  setup_env_parser = subparsers.add_parser(
      'setup_env',
      help='setup environment by building and copying dependency files')
  setup_env_parser.set_defaults(func=do_setup_env)

  # Command 'list_dep'
  list_dep_parser = subparsers.add_parser(
      'list_deps', help='list all dependency files')
  list_dep_parser.set_defaults(func=do_list_deps)

  # Command 'build'
  # TODO(szuweilin@): do not add this command if this is runned by package
  build_parser = subparsers.add_parser(
      'build', help='build a zip file including all required files')
  build_parser.add_argument(
      '-o',
      '--output',
      default='gsi_util.zip',
      help='the name of output zip file (default: gsi_util.zip)')
  build_parser.set_defaults(func=do_build)

  args = parser.parse_args(argv[1:])
  args.func(args)


if __name__ == '__main__':
  main(sys.argv)
