#
# Copyright (C) 2020 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.
#

"""Tools for running host side simulation of an OTA update."""


from __future__ import print_function

import argparse
import filecmp
import os
import shutil
import subprocess
import sys
import tempfile
import zipfile

import update_payload


def extract_file(zip_file_path, entry_name, target_file_path):
  """Extract a file from zip archive into |target_file_path|"""
  with open(target_file_path, 'wb') as out_fp:
    if isinstance(zip_file_path, zipfile.ZipFile):
      with zip_file_path.open(entry_name) as fp:
        shutil.copyfileobj(fp, out_fp)
    elif os.path.isdir(zip_file_path):
      with open(os.path.join(zip_file_path, entry_name), "rb") as fp:
        shutil.copyfileobj(fp, out_fp)


def is_sparse_image(filepath):
  with open(filepath, 'rb') as fp:
    # Magic for android sparse image format
    # https://source.android.com/devices/bootloader/images
    return fp.read(4) == b'\x3A\xFF\x26\xED'


def extract_img(zip_archive: zipfile.ZipFile, img_name, output_path):
  entry_name = "IMAGES/" + img_name + ".img"
  try:
    extract_file(zip_archive, entry_name, output_path)
  except (KeyError, FileNotFoundError) as e:
    print("Faild to extract", img_name, "from IMAGES/ dir, trying RADIO/", e)
    extract_file(zip_archive, "RADIO/" + img_name + ".img", output_path)
  if is_sparse_image(output_path):
    raw_img_path = output_path + ".raw"
    subprocess.check_output(["simg2img", output_path, raw_img_path])
    os.rename(raw_img_path, output_path)


def run_ota(source, target, payload_path, tempdir, output_dir):
  """Run an OTA on host side"""
  payload = update_payload.Payload(payload_path)
  payload.Init()
  if source and zipfile.is_zipfile(source):
    source = zipfile.ZipFile(source)
  if target and zipfile.is_zipfile(target):
    target = zipfile.ZipFile(target)
  source_exist = source and (isinstance(
      source, zipfile.ZipFile) or os.path.exists(source))
  target_exist = target and (isinstance(
      target, zipfile.ZipFile) or os.path.exists(target))

  old_partitions = []
  new_partitions = []
  expected_new_partitions = []
  for part in payload.manifest.partitions:
    name = part.partition_name
    old_image = os.path.join(tempdir, "source_" + name + ".img")
    new_image = os.path.join(tempdir, "target_" + name + ".img")
    if part.HasField("old_partition_info"):
      assert source_exist, \
          "source target file must point to a valid zipfile or directory " + \
          source
      print("Extracting source image for", name)
      extract_img(source, name, old_image)
    if target_exist:
      print("Extracting target image for", name)
      extract_img(target, name, new_image)

    old_partitions.append(old_image)
    scratch_image_name = new_image + ".actual"
    new_partitions.append(scratch_image_name)
    with open(scratch_image_name, "wb") as fp:
      fp.truncate(part.new_partition_info.size)
    expected_new_partitions.append(new_image)

  delta_generator_args = ["delta_generator", "--in_file=" + payload_path]
  partition_names = [
      part.partition_name for part in payload.manifest.partitions
  ]
  if payload.manifest.partial_update:
    delta_generator_args.append("--is_partial_update")
  if payload.is_incremental:
    delta_generator_args.append("--old_partitions=" + ":".join(old_partitions))
  delta_generator_args.append("--partition_names=" + ":".join(partition_names))
  delta_generator_args.append("--new_partitions=" + ":".join(new_partitions))

  subprocess.check_output(delta_generator_args)

  valid = True
  if not target_exist:
    for part in new_partitions:
      print("Output written to", part)
      shutil.copy(part, output_dir)
    return
  for (expected_part, actual_part, part_name) in \
          zip(expected_new_partitions, new_partitions, partition_names):
    if filecmp.cmp(expected_part, actual_part):
      print("Partition `{}` is valid".format(part_name))
    else:
      valid = False
      print(
          "Partition `{}` is INVALID expected image: {} actual image: {}"
          .format(part_name, expected_part, actual_part))

  if not valid and sys.stdout.isatty():
    input("Paused to investigate invalid partitions, press any key to exit.")


def main():
  parser = argparse.ArgumentParser(
      description="Run host side simulation of OTA package")
  parser.add_argument(
      "--source",
      help="Target file zip for the source build",
      required=False)
  parser.add_argument(
      "--target",
      help="Target file zip for the target build",
      required=False)
  parser.add_argument(
      "-o",
      dest="output_dir",
      help="Output directory to put all images, current directory by default"
  )
  parser.add_argument(
      "payload",
      help="payload.bin for the OTA package, or a zip of OTA package itself",
      nargs=1)
  args = parser.parse_args()
  print(args)

  # pylint: disable=no-member
  with tempfile.TemporaryDirectory() as tempdir:
    payload_path = args.payload[0]
    if zipfile.is_zipfile(payload_path):
      with zipfile.ZipFile(payload_path, "r") as zfp:
        payload_entry_name = 'payload.bin'
        zfp.extract(payload_entry_name, tempdir)
        payload_path = os.path.join(tempdir, payload_entry_name)
    if args.output_dir is None:
      args.output_dir = "."
    if not os.path.exists(args.output_dir):
      os.makedirs(args.output_dir, exist_ok=True)
    assert os.path.isdir(args.output_dir)
    run_ota(args.source, args.target, payload_path, tempdir, args.output_dir)


if __name__ == '__main__':
  main()
