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"

#
# Motoboot packed image format
#
# #define BOOTLDR_MAGIC "MBOOTV1"
# #define HEADER_SIZE 1024
# #define SECTOR_SIZE 512
# struct packed_images_header {
#         unsigned int num_images;
#         struct {
#                 char name[24];
#                 unsigned int start;  // start offset = HEADER_SIZE + start * SECTOR_SIZE
#                 unsigned int end;    // end offset = HEADER_SIZE + (end + 1) * SECTOR_SIZE - 1
#         } img_info[20];
#         char magic[8];  // set to BOOTLDR_MAGIC
# };
HEADER_SIZE = 1024
SECTOR_SIZE = 512
NUM_MAX_IMAGES = 20
MAGIC = "MBOOTV1\0"
class MotobootImage(object):

  def __init__(self, data, name = None):

    self.name = name
    self._unpack(data)

  def _unpack(self, data):
    """ Unpack the data blob as a motoboot image and return the list
    of contained image objects"""
    num_imgs_fmt = "<L"
    num_imgs_size = struct.calcsize(num_imgs_fmt)
    num_imgs, = struct.unpack(num_imgs_fmt, data[:num_imgs_size])

    img_info_format = "<24sLL"
    img_info_size = struct.calcsize(img_info_format)

    imgs = [ struct.unpack(img_info_format, data[num_imgs_size + i*img_info_size:num_imgs_size + (i+1)*img_info_size]) for i in range(num_imgs) ]

    magic_format = "<8s"
    magic_size = struct.calcsize(magic_format)
    magic, = struct.unpack(magic_format, data[num_imgs_size + NUM_MAX_IMAGES*img_info_size:num_imgs_size + NUM_MAX_IMAGES*img_info_size + magic_size])
    if magic != MAGIC:
      raise BadMagicError

    img_objs = []
    for name, start, end in imgs:
      start_offset = HEADER_SIZE + start * SECTOR_SIZE
      end_offset = HEADER_SIZE + (end + 1) * SECTOR_SIZE - 1
      img = common.File(trunc_to_null(name), data[start_offset:end_offset+1])
      img_objs.append(img)

    self.unpacked_images = img_objs

  def GetUnpackedImage(self, name):

    found_image = None
    for image in self.unpacked_images:
      if image.name == name:
          found_image = image
          break
    return found_image


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)
  if common.OPTIONS.full_radio:
    if not target_radio_img:
      assert False, "full radio option specified but no radio img found"
    else:
      return
  source_radio_img = FindRadio(info.source_zip)
  if not target_radio_img or not source_radio_img:
    return
  target_modem_img = MotobootImage(target_radio_img).GetUnpackedImage("modem")
  if not target_modem_img: return
  source_modem_img = MotobootImage(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.img 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"

  tf = FindRadio(info.target_zip)
  if not tf:
    # failed to read TARGET radio image: don't include any radio in update.
    print "no radio.img in target target_files; skipping install"
    # we have checked the existence of the radio image in
    # IncrementalOTA_VerifyEnd(), so it won't reach here.
    assert common.OPTIONS.full_radio == False
  else:
    tf = common.File("radio.img", tf)

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

      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 = MotobootImage(target_imagefile.data, "bootloader")
  except BadMagicError:
    assert False, "bootloader.img bad magic value"
  try:
    sm = MotobootImage(source_imagefile.data, "bootloader")
  except BadMagicError:
    print "source bootloader image is not a motoboot image. Installing complete image."
    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:
    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 image %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 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 = MotobootImage(target_imagefile.data, "radio")
  except BadMagicError:
    assert False, "radio.img bad magic value"

  try:
    source_radio_img = MotobootImage(source_imagefile.data, "radio")
  except BadMagicError:
    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')
  WriteMotobootPartitionImages(info, target_radio_img, blacklist)

def WriteIncrementalModemPartition(info, target_modem_image, source_modem_image):
  tf = target_modem_image
  sf = source_modem_image

  b = common.BlockDifference("modem", common.DataImage(tf.data),
                             common.DataImage(sf.data))

  b.WriteScript(info.script, info.output_zip)


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

  try:
    motoboot_image = MotobootImage(radio_img, "radio")
  except BadMagicError:
      assert False, "radio.img bad magic value"

  WriteMotobootPartitionImages(info, motoboot_image)

def WriteMotobootPartitionImages(info, motoboot_image, blacklist = []):
  WriteGroupedImages(info, motoboot_image.name, motoboot_image.unpacked_images, blacklist)

def WriteGroupedImages(info, group_name, images, blacklist = []):
  """ 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."""

  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:
    _, 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 = DEFAULT_BOOTLOADER_OTA_BLACKLIST):
  info.script.Print("Writing bootloader...")

  try:
    motoboot_image = MotobootImage(bootloader,"bootloader")
  except BadMagicError:
      assert False, "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.
  WriteMotobootPartitionImages(info, motoboot_image, blacklist)

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

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