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

import common
import struct

# The target does not support OTA-flashing
# the partition table, so blacklist it.
DEFAULT_BOOTLOADER_OTA_BLACKLIST = ['partition']


class BadMagicError(Exception):
  __str__ = "bad magic value"

#
# Huawei Bootloader packed image format
#
# typedef struct meta_header {
#  u32   magic;             /* 0xce1ad63c */
#  u16   major_version;     /* (0x1)-reject images with higher major versions */
#  u16   minor_version;     /* (0x0)-allow images with higer minor versions */
#  char  img_version[64];   /* Top level version for images in this meta */
#  u16   meta_hdr_sz;       /* size of this header */
#  u16   img_hdr_sz;        /* size of img_header_entry list */
# } meta_header_t;

# typedef struct img_header_entry {
#  char   ptn_name[MAX_GPT_NAME_SIZE];
#  u32    start_offset;
#  u32    size;
# } img_header_entry_t


MAGIC = 0xce1ad63c


class HuaweiBootImage(object):

  def __init__(self, data, name=None):
    self.name = name
    self.unpacked_images = None
    self._unpack(data)

  def _unpack(self, data):
    """Unpack the data blob as a Huawei boot image and return the list
    of contained image objects"""
    num_imgs_fmt = struct.Struct("<IHH64sHH")
    header = data[0:num_imgs_fmt.size]
    info = {}
    (info["magic"], info["major_version"],
     info["minor_version"], info["img_version"],
     info["meta_hdr_size"], info["img_hdr_size"]) = num_imgs_fmt.unpack(header)

    img_info_format = "<72sLL"
    img_info_size = struct.calcsize(img_info_format)
    num = info["img_hdr_size"] / img_info_size
    size = num_imgs_fmt.size
    imgs = [
         struct.unpack(
             img_info_format,
             data[size + i * img_info_size:size + (i + 1) * img_info_size])
         for i in range(num)
    ]

    if info["magic"] != MAGIC:
      raise BadMagicError

    img_objs = {}
    for name, start, end in imgs:
      if TruncToNull(name):
        img = common.File(TruncToNull(name), data[start:start + end])
        img_objs[img.name] = img

    self.unpacked_images = img_objs

  def GetUnpackedImage(self, name):
    return self.unpacked_images.get(name)


def FindRadio(zipfile):
  try:
    return zipfile.read("RADIO/radio.img")
  except KeyError:
    return None


def FullOTA_InstallEnd(info):
  try:
    bootloader_img = info.input_zip.read("RADIO/bootloader.img")
  except KeyError:
    print "no bootloader.img in target_files; skipping install"
  else:
    WriteBootloader(info, bootloader_img)

  radio_img = FindRadio(info.input_zip)
  if radio_img:
    WriteRadio(info, radio_img)
  else:
    print "no radio.img in target_files; skipping install"


def IncrementalOTA_VerifyEnd(info):
  target_radio_img = FindRadio(info.target_zip)
  source_radio_img = FindRadio(info.source_zip)
  if not target_radio_img or not source_radio_img:
    return
  target_modem_img = HuaweiBootImage(target_radio_img).GetUnpackedImage("modem")
  if not target_modem_img:
    return
  source_modem_img = HuaweiBootImage(source_radio_img).GetUnpackedImage("modem")
  if not source_modem_img:
    return
  if target_modem_img.sha1 != source_modem_img.sha1:
    info.script.CacheFreeSpaceCheck(len(source_modem_img.data))
    radio_type, radio_device = common.GetTypeAndDevice("/modem", info.info_dict)
    info.script.PatchCheck("%s:%s:%d:%s:%d:%s" % (
        radio_type, radio_device,
        len(source_modem_img.data), source_modem_img.sha1,
        len(target_modem_img.data), target_modem_img.sha1))


def IncrementalOTA_InstallEnd(info):
  try:
    target_bootloader_img = info.target_zip.read("RADIO/bootloader.img")
    try:
      source_bootloader_img = info.source_zip.read("RADIO/bootloader.img")
    except KeyError:
      source_bootloader_img = None

    if source_bootloader_img == target_bootloader_img:
      print "bootloader unchanged; skipping"
    elif source_bootloader_img == None:
      print "no bootloader in source target_files; installing complete image"
      WriteBootloader(info, target_bootloader_img)
    else:
      tf = common.File("bootloader.img", target_bootloader_img)
      sf = common.File("bootloader.img", source_bootloader_img)
      WriteIncrementalBootloader(info, tf, sf)
  except KeyError:
    print "no bootloader.img in target target_files; skipping install"

  target_radio_image = FindRadio(info.target_zip)
  if not target_radio_image:
    # failed to read TARGET radio image: don't include any radio in update.
    print "no radio.img in target target_files; skipping install"
  else:
    tf = common.File("radio.img", target_radio_image)

    source_radio_image = FindRadio(info.source_zip)
    if not source_radio_image:
      # failed to read SOURCE radio image: include the whole target
      # radio image.
      print "no radio image in source target_files; installing complete image"
      WriteRadio(info, tf.data)
    else:
      sf = common.File("radio.img", source_radio_image)

      if tf.size == sf.size and tf.sha1 == sf.sha1:
        print "radio image unchanged; skipping"
      else:
        WriteIncrementalRadio(info, tf, sf)


def WriteIncrementalBootloader(info, target_imagefile, source_imagefile):
  try:
    tm = HuaweiBootImage(target_imagefile.data, "bootloader")
  except BadMagicError:
    raise ValueError("bootloader.img bad magic value")
  try:
    sm = HuaweiBootImage(source_imagefile.data, "bootloader")
  except BadMagicError:
    print "source bootloader is not a Huawei boot img; installing complete img."
    return WriteBootloader(info, target_imagefile.data)

  # blacklist any partitions that match the source image
  blacklist = DEFAULT_BOOTLOADER_OTA_BLACKLIST
  for ti in tm.unpacked_images.values():
    if ti not in blacklist:
      si = sm.GetUnpackedImage(ti.name)
      if not si:
        continue
      if ti.size == si.size and ti.sha1 == si.sha1:
        print "target bootloader partition img %s matches source; skipping" % (
            ti.name)
        blacklist.append(ti.name)

  # If there are any images to then write them
  whitelist = [i.name for i in tm.unpacked_images.values()
               if i.name not in blacklist]
  if len(whitelist):
    # Install the bootloader, skipping any matching partitions
    WriteBootloader(info, target_imagefile.data, blacklist)


def WriteIncrementalRadio(info, target_imagefile, source_imagefile):
  try:
    target_radio_img = HuaweiBootImage(target_imagefile.data, "radio")
  except BadMagicError:
    print "Magic number mismatch in target radio image"
    raise ValueError("radio.img bad magic value")

  try:
    source_radio_img = HuaweiBootImage(source_imagefile.data, "radio")
  except BadMagicError:
    print "Magic number mismatch in source radio image"
    source_radio_img = None

  write_full_modem = True
  if source_radio_img:
    target_modem_img = target_radio_img.GetUnpackedImage("modem")
    if target_modem_img:
      source_modem_img = source_radio_img.GetUnpackedImage("modem")
      if source_modem_img:
        WriteIncrementalModemPartition(info, target_modem_img, source_modem_img)
        write_full_modem = False

  # Write the full images, skipping modem if so directed.
  #
  # NOTE: Some target flex radio images are zero-filled, and must
  #       be flashed to trigger the flex update "magic".  Do not
  #       skip installing target partition images that are identical
  #       to its corresponding source partition image.
  blacklist = []
  if not write_full_modem:
    blacklist.append("modem")
  WriteHuaweiBootPartitionImages(info, target_radio_img, blacklist)


def WriteIncrementalModemPartition(info, target_modem_image,
                                   source_modem_image):
  tf = target_modem_image
  sf = source_modem_image
  pad_tf = False
  pad_sf = False
  blocksize = 4096

  partial_tf = len(tf.data) % blocksize
  partial_sf = len(sf.data) % blocksize

  if partial_tf:
    pad_tf = True
  if partial_sf:
    pad_sf = True
  b = common.BlockDifference("modem", common.DataImage(tf.data, False, pad_tf),
                             common.DataImage(sf.data, False, pad_sf))
  b.WriteScript(info.script, info.output_zip)


def WriteRadio(info, radio_img):
  info.script.Print("Writing radio...")

  try:
    huawei_boot_image = HuaweiBootImage(radio_img, "radio")
  except BadMagicError:
    raise ValueError("radio.img bad magic value")

  WriteHuaweiBootPartitionImages(info, huawei_boot_image)


def WriteHuaweiBootPartitionImages(info, huawei_boot_image, blacklist=None):
  if blacklist is None:
    blacklist = []
  WriteGroupedImages(info, huawei_boot_image.name,
                     huawei_boot_image.unpacked_images.values(), blacklist)


def WriteGroupedImages(info, group_name, images, blacklist=None):
  """Write a group of partition images to the OTA package,
  and add the corresponding flash instructions to the recovery
  script.  Skip any images that do not have a corresponding
  entry in recovery.fstab."""
  if blacklist is None:
    blacklist = []
  for i in images:
    if i.name not in blacklist:
      WritePartitionImage(info, i, group_name)


def WritePartitionImage(info, image, group_name=None):
  filename = "%s.img" % image.name
  if group_name:
    filename = "%s.%s" % (group_name, filename)

  try:
    info.script.Print("writing partition image %s" % image.name)
    _, device = common.GetTypeAndDevice("/" + image.name, info.info_dict)
  except KeyError:
    print "skipping flash of %s; not in recovery.fstab" % image.name
    return

  common.ZipWriteStr(info.output_zip, filename, image.data)

  info.script.AppendExtra('package_extract_file("%s", "%s");' %
                          (filename, device))


def WriteBootloader(info, bootloader, blacklist=None):
  if blacklist is None:
    blacklist = DEFAULT_BOOTLOADER_OTA_BLACKLIST
  info.script.Print("Writing bootloader...")
  try:
    huawei_boot_image = HuaweiBootImage(bootloader, "bootloader")
  except BadMagicError:
    raise ValueError("bootloader.img bad magic value")

  common.ZipWriteStr(info.output_zip, "bootloader-flag.txt",
                     "updating-bootloader" + "\0" * 13)
  common.ZipWriteStr(info.output_zip, "bootloader-flag-clear.txt", "\0" * 32)

  _, misc_device = common.GetTypeAndDevice("/misc", info.info_dict)

  info.script.AppendExtra(
      'package_extract_file("bootloader-flag.txt", "%s");' % misc_device)

  # OTA does not support partition changes, so
  # do not bundle the partition image in the OTA package.
  WriteHuaweiBootPartitionImages(info, huawei_boot_image, blacklist)

  info.script.AppendExtra(
      'package_extract_file("bootloader-flag-clear.txt", "%s");' % misc_device)


def TruncToNull(s):
  if '\0' in s:
    return s[:s.index('\0')]
  else:
    return s
