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

"""Send an A/B update to an Android device over adb."""

from __future__ import print_function
from __future__ import absolute_import

import argparse
import binascii
import hashlib
import logging
import os
import re
import socket
import subprocess
import sys
import struct
import tempfile
import time
import threading
import xml.etree.ElementTree
import zipfile
import shutil

from six.moves import BaseHTTPServer


# The path used to store the OTA package when applying the package from a file.
OTA_PACKAGE_PATH = '/data/ota_package'

# The path to the payload public key on the device.
PAYLOAD_KEY_PATH = '/etc/update_engine/update-payload-key.pub.pem'

# The port on the device that update_engine should connect to.
DEVICE_PORT = 1234


def CopyFileObjLength(fsrc, fdst, buffer_size=128 * 1024, copy_length=None, speed_limit=None):
  """Copy from a file object to another.

  This function is similar to shutil.copyfileobj except that it allows to copy
  less than the full source file.

  Args:
    fsrc: source file object where to read from.
    fdst: destination file object where to write to.
    buffer_size: size of the copy buffer in memory.
    copy_length: maximum number of bytes to copy, or None to copy everything.
    speed_limit: upper limit for copying speed, in bytes per second.

  Returns:
    the number of bytes copied.
  """
  # If buffer size significantly bigger than speed limit
  # traffic would seem extremely spiky to the client.
  if speed_limit:
    print(f"Applying speed limit: {speed_limit}")
    buffer_size = min(speed_limit//32, buffer_size)

  start_time = time.time()
  copied = 0
  while True:
    chunk_size = buffer_size
    if copy_length is not None:
      chunk_size = min(chunk_size, copy_length - copied)
      if not chunk_size:
        break
    buf = fsrc.read(chunk_size)
    if not buf:
      break
    if speed_limit:
      expected_duration = copied/speed_limit
      actual_duration = time.time() - start_time
      if actual_duration < expected_duration:
        time.sleep(expected_duration-actual_duration)
    fdst.write(buf)
    copied += len(buf)
  return copied


class AndroidOTAPackage(object):
  """Android update payload using the .zip format.

  Android OTA packages traditionally used a .zip file to store the payload. When
  applying A/B updates over the network, a payload binary is stored RAW inside
  this .zip file which is used by update_engine to apply the payload. To do
  this, an offset and size inside the .zip file are provided.
  """

  # Android OTA package file paths.
  OTA_PAYLOAD_BIN = 'payload.bin'
  OTA_PAYLOAD_PROPERTIES_TXT = 'payload_properties.txt'
  SECONDARY_OTA_PAYLOAD_BIN = 'secondary/payload.bin'
  SECONDARY_OTA_PAYLOAD_PROPERTIES_TXT = 'secondary/payload_properties.txt'
  PAYLOAD_MAGIC_HEADER = b'CrAU'

  def __init__(self, otafilename, secondary_payload=False):
    self.otafilename = otafilename

    otazip = zipfile.ZipFile(otafilename, 'r')
    payload_entry = (self.SECONDARY_OTA_PAYLOAD_BIN if secondary_payload else
                     self.OTA_PAYLOAD_BIN)
    payload_info = otazip.getinfo(payload_entry)

    if payload_info.compress_type != 0:
      logging.error(
          "Expected payload to be uncompressed, got compression method %d",
          payload_info.compress_type)
    # Don't use len(payload_info.extra). Because that returns size of extra
    # fields in central directory. We need to look at local file directory,
    # as these two might have different sizes.
    with open(otafilename, "rb") as fp:
      fp.seek(payload_info.header_offset)
      data = fp.read(zipfile.sizeFileHeader)
      fheader = struct.unpack(zipfile.structFileHeader, data)
      # Last two fields of local file header are filename length and
      # extra length
      filename_len = fheader[-2]
      extra_len = fheader[-1]
      self.offset = payload_info.header_offset
      self.offset += zipfile.sizeFileHeader
      self.offset += filename_len + extra_len
      self.size = payload_info.file_size
      fp.seek(self.offset)
      payload_header = fp.read(4)
      if payload_header != self.PAYLOAD_MAGIC_HEADER:
        logging.warning(
            "Invalid header, expected %s, got %s."
            "Either the offset is not correct, or payload is corrupted",
            binascii.hexlify(self.PAYLOAD_MAGIC_HEADER),
            binascii.hexlify(payload_header))

    property_entry = (self.SECONDARY_OTA_PAYLOAD_PROPERTIES_TXT if
                      secondary_payload else self.OTA_PAYLOAD_PROPERTIES_TXT)
    self.properties = otazip.read(property_entry)


class UpdateHandler(BaseHTTPServer.BaseHTTPRequestHandler):
  """A HTTPServer that supports single-range requests.

  Attributes:
    serving_payload: path to the only payload file we are serving.
    serving_range: the start offset and size tuple of the payload.
  """

  @staticmethod
  def _parse_range(range_str, file_size):
    """Parse an HTTP range string.

    Args:
      range_str: HTTP Range header in the request, not including "Header:".
      file_size: total size of the serving file.

    Returns:
      A tuple (start_range, end_range) with the range of bytes requested.
    """
    start_range = 0
    end_range = file_size

    if range_str:
      range_str = range_str.split('=', 1)[1]
      s, e = range_str.split('-', 1)
      if s:
        start_range = int(s)
        if e:
          end_range = int(e) + 1
      elif e:
        if int(e) < file_size:
          start_range = file_size - int(e)
    return start_range, end_range

  def do_GET(self):  # pylint: disable=invalid-name
    """Reply with the requested payload file."""
    if self.path != '/payload':
      self.send_error(404, 'Unknown request')
      return

    if not self.serving_payload:
      self.send_error(500, 'No serving payload set')
      return

    try:
      f = open(self.serving_payload, 'rb')
    except IOError:
      self.send_error(404, 'File not found')
      return
    # Handle the range request.
    if 'Range' in self.headers:
      self.send_response(206)
    else:
      self.send_response(200)

    serving_start, serving_size = self.serving_range
    start_range, end_range = self._parse_range(self.headers.get('range'),
                                               serving_size)
    logging.info('Serving request for %s from %s [%d, %d) length: %d',
                 self.path, self.serving_payload, serving_start + start_range,
                 serving_start + end_range, end_range - start_range)

    self.send_header('Accept-Ranges', 'bytes')
    self.send_header('Content-Range',
                     'bytes ' + str(start_range) + '-' + str(end_range - 1) +
                     '/' + str(end_range - start_range))
    self.send_header('Content-Length', end_range - start_range)

    stat = os.fstat(f.fileno())
    self.send_header('Last-Modified', self.date_time_string(stat.st_mtime))
    self.send_header('Content-type', 'application/octet-stream')
    self.end_headers()

    f.seek(serving_start + start_range)
    CopyFileObjLength(f, self.wfile, copy_length=end_range -
                      start_range, speed_limit=self.speed_limit)


class ServerThread(threading.Thread):
  """A thread for serving HTTP requests."""

  def __init__(self, ota_filename, serving_range, speed_limit):
    threading.Thread.__init__(self)
    # serving_payload and serving_range are class attributes and the
    # UpdateHandler class is instantiated with every request.
    UpdateHandler.serving_payload = ota_filename
    UpdateHandler.serving_range = serving_range
    UpdateHandler.speed_limit = speed_limit
    self._httpd = BaseHTTPServer.HTTPServer(('127.0.0.1', 0), UpdateHandler)
    self.port = self._httpd.server_port

  def run(self):
    try:
      self._httpd.serve_forever()
    except (KeyboardInterrupt, socket.error):
      pass
    logging.info('Server Terminated')

  def StopServer(self):
    self._httpd.shutdown()
    self._httpd.socket.close()


def StartServer(ota_filename, serving_range, speed_limit):
  t = ServerThread(ota_filename, serving_range, speed_limit)
  t.start()
  return t


def AndroidUpdateCommand(ota_filename, secondary, payload_url, extra_headers):
  """Return the command to run to start the update in the Android device."""
  ota = AndroidOTAPackage(ota_filename, secondary)
  headers = ota.properties
  headers += b'USER_AGENT=Dalvik (something, something)\n'
  headers += b'NETWORK_ID=0\n'
  headers += extra_headers.encode()

  return ['update_engine_client', '--update', '--follow',
          '--payload=%s' % payload_url, '--offset=%d' % ota.offset,
          '--size=%d' % ota.size, '--headers="%s"' % headers.decode()]


class AdbHost(object):
  """Represents a device connected via ADB."""

  def __init__(self, device_serial=None):
    """Construct an instance.

    Args:
        device_serial: options string serial number of attached device.
    """
    self._device_serial = device_serial
    self._command_prefix = ['adb']
    if self._device_serial:
      self._command_prefix += ['-s', self._device_serial]

  def adb(self, command, timeout_seconds: float = None):
    """Run an ADB command like "adb push".

    Args:
      command: list of strings containing command and arguments to run

    Returns:
      the program's return code.

    Raises:
      subprocess.CalledProcessError on command exit != 0.
    """
    command = self._command_prefix + command
    logging.info('Running: %s', ' '.join(str(x) for x in command))
    p = subprocess.Popen(command, universal_newlines=True)
    p.wait(timeout_seconds)
    return p.returncode

  def adb_output(self, command):
    """Run an ADB command like "adb push" and return the output.

    Args:
      command: list of strings containing command and arguments to run

    Returns:
      the program's output as a string.

    Raises:
      subprocess.CalledProcessError on command exit != 0.
    """
    command = self._command_prefix + command
    logging.info('Running: %s', ' '.join(str(x) for x in command))
    return subprocess.check_output(command, universal_newlines=True)


def PushMetadata(dut, otafile, metadata_path):
  header_format = ">4sQQL"
  with tempfile.TemporaryDirectory() as tmpdir:
    with zipfile.ZipFile(otafile, "r") as zfp:
      extracted_path = os.path.join(tmpdir, "payload.bin")
      with zfp.open("payload.bin") as payload_fp, \
              open(extracted_path, "wb") as output_fp:
        # Only extract the first |data_offset| bytes from the payload.
        # This is because allocateSpaceForPayload only needs to see
        # the manifest, not the entire payload.
        # Extracting the entire payload works, but is slow for full
        # OTA.
        header = payload_fp.read(struct.calcsize(header_format))
        magic, major_version, manifest_size, metadata_signature_size = struct.unpack(header_format, header)
        assert magic == b"CrAU", "Invalid magic {}, expected CrAU".format(magic)
        assert major_version == 2, "Invalid major version {}, only version 2 is supported".format(major_version)
        output_fp.write(header)

        shutil.copyfileobj(payload_fp, output_fp, manifest_size + metadata_signature_size)


      return dut.adb([
          "push",
          extracted_path,
          metadata_path
      ]) == 0


def ParseSpeedLimit(arg: str) -> int:
  arg = arg.strip().upper()
  if not re.match(r"\d+[KkMmGgTt]?", arg):
    raise argparse.ArgumentError(
        "Wrong speed limit format, expected format is number followed by unit, such as 10K, 5m, 3G (case insensitive)")
  unit = 1
  if arg[-1].isalpha():
    if arg[-1] == "K":
      unit = 1024
    elif arg[-1] == "M":
      unit = 1024 * 1024
    elif arg[-1] == "G":
      unit = 1024 * 1024 * 1024
    elif arg[-1] == "T":
      unit = 1024 * 1024 * 1024 * 1024
    else:
      raise argparse.ArgumentError(
          f"Unsupported unit for download speed: {arg[-1]}, supported units are K,M,G,T (case insensitive)")
  return int(float(arg[:-1]) * unit)


def main():
  parser = argparse.ArgumentParser(description='Android A/B OTA helper.')
  parser.add_argument('otafile', metavar='PAYLOAD', type=str,
                      help='the OTA package file (a .zip file) or raw payload \
                      if device uses Omaha.')
  parser.add_argument('--file', action='store_true',
                      help='Push the file to the device before updating.')
  parser.add_argument('--no-push', action='store_true',
                      help='Skip the "push" command when using --file')
  parser.add_argument('-s', type=str, default='', metavar='DEVICE',
                      help='The specific device to use.')
  parser.add_argument('--no-verbose', action='store_true',
                      help='Less verbose output')
  parser.add_argument('--public-key', type=str, default='',
                      help='Override the public key used to verify payload.')
  parser.add_argument('--extra-headers', type=str, default='',
                      help='Extra headers to pass to the device.')
  parser.add_argument('--secondary', action='store_true',
                      help='Update with the secondary payload in the package.')
  parser.add_argument('--no-slot-switch', action='store_true',
                      help='Do not perform slot switch after the update.')
  parser.add_argument('--no-postinstall', action='store_true',
                      help='Do not execute postinstall scripts after the update.')
  parser.add_argument('--allocate-only', action='store_true',
                      help='Allocate space for this OTA, instead of actually \
                        applying the OTA.')
  parser.add_argument('--verify-only', action='store_true',
                      help='Verify metadata then exit, instead of applying the OTA.')
  parser.add_argument('--no-care-map', action='store_true',
                      help='Do not push care_map.pb to device.')
  parser.add_argument('--perform-slot-switch', action='store_true',
                      help='Perform slot switch for this OTA package')
  parser.add_argument('--perform-reset-slot-switch', action='store_true',
                      help='Perform reset slot switch for this OTA package')
  parser.add_argument('--wipe-user-data', action='store_true',
                      help='Wipe userdata after installing OTA')
  parser.add_argument('--vabc-none', action='store_true',
                      help='Set Virtual AB Compression algorithm to none, but still use Android COW format')
  parser.add_argument('--disable-vabc', action='store_true',
                      help='Option to enable or disable vabc. If set to false, will fall back on A/B')
  parser.add_argument('--enable-threading', action='store_true',
                      help='Enable multi-threaded compression for VABC')
  parser.add_argument('--batched-writes', action='store_true',
                      help='Enable batched writes for VABC')
  parser.add_argument('--speed-limit', type=str,
                      help='Speed limit for serving payloads over HTTP. For '
                      'example: 10K, 5m, 1G, input is case insensitive')

  args = parser.parse_args()
  if args.speed_limit:
    args.speed_limit = ParseSpeedLimit(args.speed_limit)

  logging.basicConfig(
      level=logging.WARNING if args.no_verbose else logging.INFO)

  start_time = time.perf_counter()

  dut = AdbHost(args.s)

  server_thread = None
  # List of commands to execute on exit.
  finalize_cmds = []
  # Commands to execute when canceling an update.
  cancel_cmd = ['shell', 'su', '0', 'update_engine_client', '--cancel']
  # List of commands to perform the update.
  cmds = []

  help_cmd = ['shell', 'su', '0', 'update_engine_client', '--help']

  metadata_path = "/data/ota_package/metadata"
  if args.allocate_only:
    with zipfile.ZipFile(args.otafile, "r") as zfp:
      headers = zfp.read("payload_properties.txt").decode()
    if PushMetadata(dut, args.otafile, metadata_path):
      dut.adb([
          "shell", "update_engine_client", "--allocate",
          "--metadata={} --headers='{}'".format(metadata_path, headers)])
    # Return 0, as we are executing ADB commands here, no work needed after
    # this point
    return 0
  if args.verify_only:
    if PushMetadata(dut, args.otafile, metadata_path):
      dut.adb([
          "shell", "update_engine_client", "--verify",
          "--metadata={}".format(metadata_path)])
    # Return 0, as we are executing ADB commands here, no work needed after
    # this point
    return 0
  if args.perform_slot_switch:
    assert PushMetadata(dut, args.otafile, metadata_path)
    dut.adb(["shell", "update_engine_client",
            "--switch_slot=true", "--metadata={}".format(metadata_path), "--follow"])
    return 0
  if args.perform_reset_slot_switch:
    assert PushMetadata(dut, args.otafile, metadata_path)
    dut.adb(["shell", "update_engine_client",
            "--switch_slot=false", "--metadata={}".format(metadata_path)])
    return 0

  if args.no_slot_switch:
    args.extra_headers += "\nSWITCH_SLOT_ON_REBOOT=0"
  if args.no_postinstall:
    args.extra_headers += "\nRUN_POST_INSTALL=0"
  if args.wipe_user_data:
    args.extra_headers += "\nPOWERWASH=1"
  if args.vabc_none:
    args.extra_headers += "\nVABC_NONE=1"
  if args.disable_vabc:
    args.extra_headers += "\nDISABLE_VABC=1"
  if args.enable_threading:
    args.extra_headers += "\nENABLE_THREADING=1"
  if args.batched_writes:
    args.extra_headers += "\nBATCHED_WRITES=1"

  with zipfile.ZipFile(args.otafile) as zfp:
    CARE_MAP_ENTRY_NAME = "care_map.pb"
    if CARE_MAP_ENTRY_NAME in zfp.namelist() and not args.no_care_map:
      # Need root permission to push to /data
      dut.adb(["root"])
      with tempfile.NamedTemporaryFile() as care_map_fp:
        care_map_fp.write(zfp.read(CARE_MAP_ENTRY_NAME))
        care_map_fp.flush()
        dut.adb(["push", care_map_fp.name,
                "/data/ota_package/" + CARE_MAP_ENTRY_NAME])

  if args.file:
    # Update via pushing a file to /data.
    device_ota_file = os.path.join(OTA_PACKAGE_PATH, 'debug.zip')
    payload_url = 'file://' + device_ota_file
    if not args.no_push:
      data_local_tmp_file = '/data/local/tmp/debug.zip'
      cmds.append(['push', args.otafile, data_local_tmp_file])
      cmds.append(['shell', 'su', '0', 'mv', data_local_tmp_file,
                   device_ota_file])
      cmds.append(['shell', 'su', '0', 'chcon',
                   'u:object_r:ota_package_file:s0', device_ota_file])
    cmds.append(['shell', 'su', '0', 'chown', 'system:cache', device_ota_file])
    cmds.append(['shell', 'su', '0', 'chmod', '0660', device_ota_file])
  else:
    # Update via sending the payload over the network with an "adb reverse"
    # command.
    payload_url = 'http://127.0.0.1:%d/payload' % DEVICE_PORT
    serving_range = (0, os.stat(args.otafile).st_size)
    server_thread = StartServer(args.otafile, serving_range, args.speed_limit)
    cmds.append(
        ['reverse', 'tcp:%d' % DEVICE_PORT, 'tcp:%d' % server_thread.port])
    finalize_cmds.append(['reverse', '--remove', 'tcp:%d' % DEVICE_PORT])

  if args.public_key:
    payload_key_dir = os.path.dirname(PAYLOAD_KEY_PATH)
    cmds.append(
        ['shell', 'su', '0', 'mount', '-t', 'tmpfs', 'tmpfs', payload_key_dir])
    # Allow adb push to payload_key_dir
    cmds.append(['shell', 'su', '0', 'chcon', 'u:object_r:shell_data_file:s0',
                 payload_key_dir])
    cmds.append(['push', args.public_key, PAYLOAD_KEY_PATH])
    # Allow update_engine to read it.
    cmds.append(['shell', 'su', '0', 'chcon', '-R', 'u:object_r:system_file:s0',
                 payload_key_dir])
    finalize_cmds.append(['shell', 'su', '0', 'umount', payload_key_dir])

  try:
    # The main update command using the configured payload_url.
    update_cmd = AndroidUpdateCommand(args.otafile, args.secondary,
                                        payload_url, args.extra_headers)
    cmds.append(['shell', 'su', '0'] + update_cmd)

    for cmd in cmds:
      dut.adb(cmd)
  except KeyboardInterrupt:
    dut.adb(cancel_cmd)
  finally:
    if server_thread:
      server_thread.StopServer()
    for cmd in finalize_cmds:
      dut.adb(cmd, 5)

  logging.info('Update took %.3f seconds', (time.perf_counter() - start_time))
  return 0


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