#!/usr/bin/env python
#
# Copyright (C) 2019 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.

"""
Signs a standalone APEX file.

Usage:  sign_apex [flags] input_apex_file output_apex_file

  --avbtool <avbtool>
      Optional flag that specifies the AVB tool to use. Defaults to `avbtool`.

  --container_key <key>
      Mandatory flag that specifies the container signing key.

  --payload_key <key>
      Mandatory flag that specifies the payload signing key.

  --payload_extra_args <args>
      Optional flag that specifies any extra args to be passed to payload signer
      (e.g. --payload_extra_args="--signing_helper_with_files /path/to/helper").

  -e  (--extra_apks)  <name,name,...=key>
      Add extra APK name/key pairs. This is useful to sign the apk files in the
      apex payload image.

  --codename_to_api_level_map Q:29,R:30,...
      A Mapping of codename to api level.  This is useful to provide sdk targeting
      information to APK Signer.
"""

import logging
import shutil
import sys

import apex_utils
import common

logger = logging.getLogger(__name__)


def SignApexFile(avbtool, apex_file, payload_key, container_key, no_hashtree,
                 apk_keys=None, signing_args=None, codename_to_api_level_map=None):
  """Signs the given apex file."""
  with open(apex_file, 'rb') as input_fp:
    apex_data = input_fp.read()

  return apex_utils.SignApex(
      avbtool,
      apex_data,
      payload_key=payload_key,
      container_key=container_key,
      container_pw=None,
      codename_to_api_level_map=codename_to_api_level_map,
      no_hashtree=no_hashtree,
      apk_keys=apk_keys,
      signing_args=signing_args)


def main(argv):

  options = {}

  def option_handler(o, a):
    if o == '--avbtool':
      options['avbtool'] = a
    elif o == '--container_key':
      # Strip the suffix if any, as common.SignFile expects no suffix.
      DEFAULT_CONTAINER_KEY_SUFFIX = '.x509.pem'
      if a.endswith(DEFAULT_CONTAINER_KEY_SUFFIX):
        a = a[:-len(DEFAULT_CONTAINER_KEY_SUFFIX)]
      options['container_key'] = a
    elif o == '--payload_key':
      options['payload_key'] = a
    elif o == '--payload_extra_args':
      options['payload_extra_args'] = a
    elif o == '--codename_to_api_level_map':
      versions = a.split(",")
      for v in versions:
        key, value = v.split(":")
        if 'codename_to_api_level_map' not in options:
          options['codename_to_api_level_map'] = {}
        options['codename_to_api_level_map'].update({key: value})
    elif o in ("-e", "--extra_apks"):
      names, key = a.split("=")
      names = names.split(",")
      for n in names:
        if 'extra_apks' not in options:
          options['extra_apks'] = {}
        options['extra_apks'].update({n: key})
    else:
      return False
    return True

  args = common.ParseOptions(
      argv, __doc__,
      extra_opts='e:',
      extra_long_opts=[
          'avbtool=',
          'codename_to_api_level_map=',
          'container_key=',
          'payload_extra_args=',
          'payload_key=',
          'extra_apks=',
      ],
      extra_option_handler=option_handler)

  if (len(args) != 2 or 'container_key' not in options or
      'payload_key' not in options):
    common.Usage(__doc__)
    sys.exit(1)

  common.InitLogging()

  signed_apex = SignApexFile(
      options.get('avbtool', 'avbtool'),
      args[0],
      options['payload_key'],
      options['container_key'],
      no_hashtree=False,
      apk_keys=options.get('extra_apks', {}),
      signing_args=options.get('payload_extra_args'),
      codename_to_api_level_map=options.get(
          'codename_to_api_level_map', {}))
  shutil.copyfile(signed_apex, args[1])
  logger.info("done.")


if __name__ == '__main__':
  try:
    main(sys.argv[1:])
  except common.ExternalError:
    logger.exception("\n   ERROR:\n")
    sys.exit(1)
  finally:
    common.Cleanup()
