#!/usr/bin/env python

# Copyright (c) 2011 The Chromium OS Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.

import binascii
import collections
import hashlib
import optparse
import os
import re
import shutil
import struct
import sys

from tools import CmdError
from tools import Tools
from fdt import Fdt

# Attributes defined outside __init__
#pylint: disable=W0201

# TODO(sjg): Once we have a stable fdt, write some unit tests for this

# TODO(clchiou): Rewrite this part after official flashmap implementation is
# pulled into Chromium OS code base.

# Use this to find the FDT containing the flashmap
FDTMAP_SIGNATURE = '__FDTM__'

# constants imported from lib/fmap.h
FMAP_SIGNATURE = "__FMAP__"
FMAP_VER_MAJOR = 1
FMAP_VER_MINOR = 0
FMAP_STRLEN = 32

FMAP_AREA_STATIC = 1 << 0
FMAP_AREA_COMPRESSED = 1 << 1
FMAP_AREA_RO = 1 << 2

FMAP_HEADER_FORMAT = "<8sBBQI%dsH" % (FMAP_STRLEN)
FMAP_AREA_FORMAT = "<II%dsH" % (FMAP_STRLEN)

FMAP_HEADER_NAMES = (
    'signature',
    'ver_major',
    'ver_minor',
    'base',
    'image_size',
    'name',
    'nareas',
)

FMAP_AREA_NAMES = (
    'offset',
    'size',
    'name',
    'flags',
)

# A useful named tuple.
Value = collections.namedtuple('Value', ['node', 'key', 'params'])

class ConfigError(Exception):
  """A configuration error, normally a mistake in the fdt."""
  pass


class PackError(Exception):
  """A packing error, such as a file being too large for its area."""
  pass


class Entry(dict):
  """The base class for an entry type.

  All entry types are subclasses of this class. It is basically a dictionary
  with a few methods to check that the supplied data is value.

  Subclasses should implement the following methods:

    GetData(): To return the data for this entry as a string.
    RunTools(): To run any required tools to create the data.

  Potentially in the future we could add PutData() to write data from a packed
  image file back into an entry, to allow an image file to be updated.

  Properties which we need in our dictionary:
    pack: The PackFirmware object (essentially this is our parent)
    offset: Byte offset of area.
    size: Size of area in bytes.
    name: Name of area.
    required: True if this entry is required in the image, False if not

  Properties which we create:
    value: The value that we obtain for this entry. This is a list of
        filenames.
  """
  def __init__(self, props):
    super(Entry, self).__init__(props)
    self._CheckFields(('offset', 'size', 'name'))

  def __getattr__(self, name):
    return self[name]

  def __setattr__(self, name, value):
    self[name] = value

  def _CheckFields(self, fields):
    """Check that listed fields are present.

    Args:
      fields: List of field names to check for.

    Raises:
      ConfigError: if a field is not present.
    """
    for f in fields:
      if f not in self:
        raise ConfigError('Entry %s: missing required field: %s' %
            (self['name'], f))

  def _CheckFieldsInt(self, fields):
    """Check that listed fields are present, and convert them to ints.

    Args:
      fields: List of field names to check for.

    Raises:
      ConfigError: if a field is not present or cannot be converted to an int.
    """
    self._CheckFields(fields)
    for f in fields:
      try:
        self[f] = int(self[f])
      except ValueError:
        raise ConfigError("Entry %s, property %s: could not convert '%s'"
            " to integer" % (self['name'], f, self[f]))

  def GetOverlap(self, entry):
    """Returns the amount by which we overlap with the supplied entry.

    Args:
      entry: Entry to check.

    Returns:
      Amount of overlap:
        0: the entries butt up together.
        <0: there is a gap bewteen the entries.
        >0: there is overlap.
    """
    a = [self.offset, self.offset + self.size]
    b = [entry.offset, entry.offset + entry.size]
    return min(a[1], b[1]) - max(a[0], b[0])

  def GetData(self):
    """Method implemented by subclasses to return data for the entry.

    Returns:
      String containing entry data.
    """
    raise PackError('class Entry does not implement GetEntry()')

  def RunTools(self, tools, out, tmpdir):
    """Method implemented by subclasses to run required tools.

    Some entry types require running external tools to create their data.
    This method provides a convenient way of doing this. The supplied
    temporary directory can be used to store files. These should ideally
    not be deleted by this method, since the user may wish to see them
    later.

    Args:
      tools: Tools object to use to run tools.
      out: Output object to send output to
      tmpdir: Temporary directory to use to create required files.
    """
    pass


class EntryFmapArea(Entry):
  """A base class for things that actually produce data for the image.

  Properties:
    flags: The FMAP flags, which is an integer made up from the bit values in
        FMAP_AREA_...
  """
  def __init__(self, props):
    super(EntryFmapArea, self).__init__(props)
    self._CheckFields(('flags',))

  def GetData(self):
    """This section is empty"""
    return ''


class EntryFmap(EntryFmapArea):
  """An entry which contains an Fmap section

  Properties:
    base: Base offset of flash device (normally 0).
    size: Size of the flash device (2MB or 4MB typically).
    nareas: Number of areas in the FMAP = number of sections.
    entries: The list of entries to put in the FMAP.
  """

  def __init__(self, props):
    super(EntryFmap, self).__init__(props)
    self._CheckFieldsInt(('ver_major', 'ver_minor'))

  def SetEntries(self, base, image_size, entries):
    self['base'] = base
    self['image_size'] = image_size
    self['nareas'] = len(entries)
    self['entries'] = entries

  def GetData(self):
    def _FormatBlob(fmt, names, obj):
      params = [obj[name] for name in names]
      return struct.pack(fmt, *params)

    self._CheckFields(('base', 'size'))
    self['signature'] = FMAP_SIGNATURE
    blob = _FormatBlob(FMAP_HEADER_FORMAT, FMAP_HEADER_NAMES, self)
    for entry in self.entries:
      blob += _FormatBlob(FMAP_AREA_FORMAT, FMAP_AREA_NAMES, entry)

    return blob


class EntryFdtMap(EntryFmapArea):
  """An entry which contains an FDT-based flashmap

  Properties:
    base: Base offset of flash device (normally 0).
    size: Size of the flash device (2MB or 4MB typically).
  """

  def __init__(self, props):
    super(EntryFdtMap, self).__init__(props)

  # We could potentially include only the flashmap node, but for now put
  # the entire FDT in this region. It provides easy access to all
  # configuration.
  def GetData(self):
    data = self.pack.tools.ReadFile(self.pack.props['fdtmap'])
    crc32 = binascii.crc32(data) & 0xffffffff
    blob = struct.pack('<8sLL', FDTMAP_SIGNATURE, len(data), crc32)
    blob += data

    return blob


class EntryWiped(EntryFmapArea):
  """This entry will be wiped to a particular byte value.

  Properties:
    wipe_value: byte value to set area to.
  """
  def __init__(self, props):
    super(EntryWiped, self).__init__(props)
    self._CheckFields(('wipe_value',))
    if self.wipe_value:
      self.wipe_value = chr(int(self.wipe_value))
    else:
      self.wipe_value = chr(0)
    if len(self.wipe_value) != 1:
      raise ConfigError('wipe_value out of range [00:ff]: %s' %
                        repr(self.wipe_value))

  def GetData(self):
    return self.wipe_value * self.size


class EntryBlobString(EntryFmapArea):
  """This entry contains a single string.

  The string is placed in the area.

  Properties:
    self.value: The string value to store.
  """
  def __init__(self, props):
    super(EntryBlobString, self).__init__(props)

  def GetData(self):
    return self.value[0]


class EntryIfd(EntryFmapArea):
  """This entry marks the use of an Intel Firmware Descriptor.

  The entry itself covers the 'Intel' part of the firmware, containing the
  firmware descriptor and management engine. When this entry appears in a
  flash map, we strip it off the image, and use ifdtool to place the rest
  of the image into a provided skeleton file (which contains the management
  engine and a skeleton firmware descriptor).
  """
  def __init__(self, props):
    super(EntryIfd, self).__init__(props)

  def ProduceFinalImage(self, tools, out, tmpdir, image_fname):
    """Produce the final image for an Intel ME system

    Some Intel systems require that an image contains the Management Engine
    firmware, and also a firmware descriptor.

    This function takes the existing image, removes the front part of it,
    and replaces it with these required pieces using ifdtool.

    Args:
      tools: Tools object to use to run tools.
      out: Output object to send output to
      tmpdir: Temporary directory to use to create required files.
      image_fname: Output image filename
    """
    out.Progress('Setting up Intel ME')
    data = tools.ReadFile(image_fname)

    # We can assume that the ifd section is at the start of the image.
    if self.offset != 0:
      raise ConfigError('IFD section must be at offset 0 in the image')
    data = data[self.size:]
    input_fname = os.path.join(tmpdir, 'ifd-input.bin')
    tools.WriteFile(input_fname, data)
    ifd_output = os.path.join(tmpdir, 'image.ifd')

    # This works by modifying a skeleton file.
    shutil.copyfile(tools.Filename(self.pack.props['skeleton']), ifd_output)
    args = ['-i', 'BIOS:%s' % input_fname, ifd_output]
    tools.Run('ifdtool', args)

    # ifdtool puts the output in a file with '.new' tacked on the end.
    shutil.move(ifd_output + '.new', image_fname)
    tools.OutputSize('IFD image', image_fname)

class EntryBlob(EntryFmapArea):
  """This entry contains a binary blob.

  Properties:
    self.value: The filename to read to obtain the blob data.
  """
  def __init__(self, props, params):
    super(EntryBlob, self).__init__(props)
    self.params = params
    if 'compress' not in self:
      self.compress = None
    self.with_index = 'with_index' in props

  def GetData(self):
    return self.pack.tools.ReadFileAndConcat(
        self.value, self.compress, self.with_index)[0]


class EntryKeyBlock(EntryFmapArea):
  """This entry contains a vblock

  Properties:
    keyblock: The filename of the keyblock to use (within the keydir)
        (e.g. 'firmware.keyblock')
    signprivate: Private key filename (e.g. 'firmware_data_key.vbprivk')
    keynelkey: Kernel key filename (e.g. 'kernel_subkey.vbpubk')
    version: Version of vblock (generally 1)
  """
  def __init__(self, props):
    super(EntryKeyBlock, self).__init__(props)
    self._CheckFields(('keyblock', 'signprivate', 'kernelkey'))
    self._CheckFieldsInt(('version', 'preamble_flags'))
    if 'compress' not in self:
      self.compress = None
    self.with_index = 'with_index' in props

# pylint can't figure out that self.value is set by now
#pylint: disable=E0203

  def RunTools(self, tools, out, tmpdir):
    """Create a vblock for the given firmware image"""
    self.path = os.path.join(tmpdir, 'vblock.%s' % self.label)
    input_data = os.path.join(tmpdir, 'input.%s' % self.label)
    try:
      prefix = self.pack.props['keydir'] + '/'

      # Join up the data files to be signed
      data = self.pack.tools.ReadFileAndConcat(
        self.value, self.compress, self.with_index)[0]
      tools.WriteFile(input_data, data)
      args = [
          '--vblock', self.path,
          '--keyblock', prefix + self.keyblock,
          '--signprivate', prefix + self.signprivate,
          '--version', '%d' % self.version,
          '--fv', input_data,
          '--kernelkey', prefix + self.kernelkey,
          '--flags', '%d' % self.preamble_flags,
      ]
      out.Notice("Sign '%s' into %s" % (', '.join(self.value), self.label))
      stdout = tools.Run('vbutil_firmware', args)
      out.Debug(stdout)

      # Update value to the actual filename to be used
      self.value = [self.path]
    except CmdError as err:
      raise PackError('Cannot make key block: vbutil_firmware failed\n%s' %
                      err)

  def GetData(self):
    fd = open(self.path, 'rb')
    data = fd.read()
    fd.close()
    return data


class PackFirmware:
  """Class for packing a firmware image

  A firmware image consists of a number of areas, called entries here.
  Together they cover the entire firmware device from start to finish.

  We use the fdt to define the format of the output - things like the
  name, start and size of each entry, as well as what type of thing
  to pack in there.

  We maintain a list of available data files (in self.props) and these can be
  requested by each entry. Each entry is a subclass of Entry, such as
  EntryBlob which handles the 'blob' entry type.

  One of the entry types is the fmap (flash map). It basically has a header
  and a representation of the list of sections. We create this from the fdt
  auotmatically. You can find this format documented here:

      http://code.google.com/p/flashmap/wiki/FmapSpec


  The following methods must be called in order:

    SetupFiles
    SelectFdt
    PackImage
  """
  def __init__(self, tools, output):
    """
    Args:
      output: A method to call to diplay output:
                def output(msg):
                Args:
                  msg: Message to output.
      tools: A tools object for calling external tools.
      verbose: 0 for silent, 1 for progress only, 2 for some info, 3 for
          full info, 4 for debug info including sub-tool output.
    """
    self.props = {}             # Properties / files we know about.
    self.entries = []           # The entries in the flash image.
    self._out = output
    self.tools = tools
    self.use_efs = False        # Early firmware selection

  def _GetFlags(self, props):
    """Create the fmap flags value from the given properties.

    Args:
      props: Dictionary containing properties.

    Returns
      Integer containing flags from _FMAP_AREA_...
    """
    flags = FMAP_AREA_STATIC
    if 'read-only' in props:
      flags |= FMAP_AREA_RO
    if 'compressed' in props:
      flags |= FMAP_AREA_COMPRESSED
    return flags

  def _CreateEntry(self, node, props):
    """Create an entry based on a node in the fdt.

    For example this fdt line:

      type = "blob signed";

    means it is a 'blob' type and will create an EntryBlob, and the blob
    used will be self.props['signed'].

    Args:
      node: The node to use, e.g. /flash/ro-stub
      props: Doctionary containing all properties from the node.

    Returns:
      An entry set up and ready for packing.

    Raises:
      ValueError: If fdt has an unknown entry type.
    """
    entry_list = ['empty']

    # Try to use the early-firmware-selection type if we are in that mode.
    if self.use_efs:
      entry_list = props.get('type,efs', 'empty').split()
    if entry_list[0] == 'empty':
      entry_list = props.get('type', 'empty').split()
    ftype = entry_list[0]
    if ftype == 'empty':
      ftype = ''
    key = None
    if len(entry_list) > 1:
      key = entry_list[1]
    params = entry_list[2:]

    # Create an entry of the correct type.
    entry = None
    if not ftype:
      entry = EntryFmapArea(props)
    elif ftype == 'blob':
      entry = EntryBlob(props, params)
    elif ftype == 'wiped':
      entry = EntryWiped(props)
    elif ftype == 'keyblock':
      entry = EntryKeyBlock(props)
    elif ftype == 'blobstring':
      entry = EntryBlobString(props)
    elif ftype == 'fmap':
      entry = EntryFmap(props)
    elif ftype == 'ifd':
      entry = EntryIfd(props)
    elif ftype == 'fdtmap':
      entry = EntryFdtMap(props)
    else:
      raise ValueError('%s: unknown entry type' % ftype)

    entry.pack = self
    entry.node = node
    entry.key = key
    entry.required = 'required' in props
    entry.ftype = ftype
    return entry

  def _IsRequired(self, entry):
    """Check if an entry is required in the final image.

    Args:
      entry: Entry to check

    Returns:
      True if this entry must be included, False if not.
    """
    return entry.required

  def SetupFiles(self, boot, signed, gbb, fwid, keydir):
    """Set up files required for packing the firmware.

    Args:
      boot: Filename of bootloader image.
      signed: Filename of signed bootloader image.
      gbb: Filename of Google Binary Block (GBB).
      fwid: String containing the firmware ID.
      keydir: Key directory to use (containing signing keys).
    """
    self.props['boot'] = boot
    self.props['signed'] = signed
    self.props['gbb'] = gbb
    self.props['fwid'] = fwid
    self.keydir = keydir

  def _CheckOverlap(self):
    """Check that no entries overlap each other.

    We only allow section areas to overlap - anything with actual data in it
    must not overlap.

    Returns:
      True if all entries are required in the image, else False
    """
    required = filter(self._IsRequired, self.entries)
    entries = sorted(required, key=lambda e: e.offset)
    all_entries = len(self.entries) == len(required)
    for e1, e2 in zip(entries, entries[1:]):
      # Allow overlap between "pure" fmap areas, but not any of its subclasses
      # Here we exploit the fact that Entry is a new-style class
      if type(e1) is EntryFmapArea or type(e2) is EntryFmapArea:
        continue

      overlap = e1.GetOverlap(e2)
      if overlap > 0:
        raise ValueError('Flash map entries overlap by %d bytes: '
            '%s: %08x-%08x, %s: %08x-%08x' %
            (overlap, e1.label, e1.offset, e1.offset + e1.size,
             e2.label, e2.offset, e2.offset + e2.size))
      elif overlap is not 0:
        self._out.Warning('Warning: Flash map has a gap of %d bytes: '
            '%s: %08x-%08x, %s: %08x-%08x' %
            (-overlap, e1.label, e1.offset, e1.offset + e1.size,
             e2.label, e2.offset, e2.offset + e2.size))

    return all_entries

  def SelectFdt(self, fdt, board=None):
    """Scan FDT and build entry objects.

    This creates a list of entry objects which we can later use to generate
    a firmware image. Each entry's properties are set up correcty but at this
    stage no data is processed. The result is a list of entries in
    self.entries.

    Args:
      fdt: fdt object containing the device tree.
      board: Name of board type if known (None if not known).

    Raises:
      ConfigError if an error is detected in the fdt configuration.
    """
    def _AddNode(node, props):
      """Add a new flash map node to the entry list.

      Args:
        node: Name of node to read from
        props: Dictionary containing properties of the node
      """
      align = int(props.get('align', '1'))
      align_mask = align - 1
      if align == 0 or (align & align_mask) != 0:
        raise ValueError("Invalid alignment %d in node '%s'" % props['label'])
      # Read the two cells from the node's /reg property to get entry extent.
      reg = props.get('reg', None)
      if reg:
        offset, size = fdt.DecodeIntList(node, 'reg', reg, 2)
        if (offset & align_mask) or (size & align_mask):
          raise ValueError("Alignment of %d conflicts with 'reg' setting in"
                           "node '%s': offset=%#08x, size=%#08x" %
                           (align, props['label'], offset, size))
      else:
        size = props.get('size', None)
        if not size:
          raise ValueError("Must specify either 'reg' or 'size' in flash"
                           "node '%s'" % props['label'])
        size = int(size)
        offset = self.upto_offset
        offset = (offset + align_mask) & ~align_mask

      props['node'] = node
      props['offset'] = offset
      props['size'] = size

      # The section names must be upper case with underscores, for other tools
      props['name'] = re.sub('-', '_', props['label']).upper()
      props['flags'] = self._GetFlags(props)
      try:
        entry = self._CreateEntry(node, props)
        self.entries.append(entry)

      except ConfigError as err:
        raise ValueError('Config error: %s' % err)

      if entry.ftype:
        self.upto_offset = offset + size
      else:
        self.upto_offset = offset
      if entry.required:
        self.required_count += 1
      if entry.key == 'signed':
        self.first_blob_entry = entry

    self.fdt = fdt
    root = '/flash'

    # Current offset to use for entries with only a 'size' property.
    self.upto_offset = 0
    self.required_count = 0
    self.first_blob_entry = None

    if not fdt.GetProp(root, 'reg', ''):
      raise ValueError("No /flash present in fdt, and no available default"
                        " for board '%s'" % board)
    self.image_size = int(fdt.GetIntList(root, 'reg', 2)[1])

    # Scan the flash map in the fdt, creating a list of Entry objects.
    children = fdt.GetChildren(root)

    for child in children:
      node = root + '/' + child
      props = fdt.GetProps(node, True)

      _AddNode(node, props)

      # If there was only a 'size' property, write a full 'reg' property
      # based on the offset we calculated
      if not props.get('reg'):
        fdt.PutIntList(node, 'reg', [props['offset'], props['size']])

  def GetBlobList(self):
    """Generate a list of blob types that we are going to need.

    Returns:
      List of blob type strings
    """
    blob_set = set()
    for entry in self.entries:
      if isinstance(entry, EntryBlob):
        blob_set.update(entry.key.split(','))

    return list(blob_set)

  def GetBlobParams(self, blob_type):
    """Returns the parameters for a blob of the given type.

    There should be only one blob of this type in the entire flashmap.

    Args:
      blob_type: Type of the blob (e.g. 'exynos-bl2')

    Raises:
      ValueError if the blob cannot be found.

    Returns:
      The list of parameters for this blob, which may be empty
    """
    for entry in self.entries:
      if isinstance(entry, EntryBlob):
        if entry.key == blob_type:
          return entry.params

    raise ValueError("Blob type '%s' cannot be found" % blob_type)

  def AddProperty(self, name, value):
    """Add a new property which can be used by the fdt.

    Args:
      name: Name of property
      value: Value of property (typically a filename)
    """
    if not value:
      raise CmdError("Cannot find value for entry property '%s'" % name)
    self.props[name] = value

  def GetProperty(self, name):
    """Get the value of a property required by the fdt.

    Args:
      name: Name of property

    Returns:
      Value of property, normally a filename string
    """
    return self.props.get(name, None)

  def ConcatPropContents(self, prop_list, compress, with_index):
    """Read, concatenate and return the contents of the listed props.

    Each property references a filename. We read the contents of each
    file and join it together.

    Each section starts on a 32-bit boundary.

    Args:
      prop_list: List of properties to process
      compress: compression type, like 'lzo', None for no compression
      with_index: Wether an index structure should be prepended
          See ReadFileAndConcat for more details.

    Returns:
      Tuple:
        Contents of the files (as a string), optionally with an index
          prepended (see ReadFileAndConcat for details)
        Directory of the position of the contents, as a dictionary:
          key: Name of the property
          value: List containing:
            offset of the start of this property's data
            size of this property's data
    """
    filenames = [self.props[prop] for prop in prop_list]
    data, offset, length = \
        self.tools.ReadFileAndConcat(filenames, compress, with_index)
    directory = {}
    for i in xrange(len(prop_list)):
      directory[prop_list[i]] = [offset[i], length[i]]
    return data, directory

# For some weird reason pylint presumes that sha256 is not in hashlib
#pylint: disable=E1101

  def UpdateBlobPositionsAndHashes(self, fdt):
    """Record position and size of all blob members in the FDT.

    Some blobs have multiple files within them. We want a way to
    access these individiually. We do this by adding a subnode for
    each, and putting the offset and size information in there.

    This function scans for blobs with more than one file and adds
    a 'reg' property to the subnode for each file. It also adds 'hash'
    nodes with the sha 256 hash of the file's contents.

    Note: Since one of the members may in fact be the fdt, and we are
    updating the fdt, we may change the size it. To get around this,
    we perform two passes of the algorithm. On the second pass we will
    be writing data that is already there, so the fdt size will not
    change.
    """
    for _ in range(0, 2):
      for entry in self.entries:
        if isinstance(entry, EntryBlob):
          self._out.Info("Updating blob positions in fdt for '%s'" % entry.key)
          data, directory = self.ConcatPropContents(
              entry.key.split(','), None, entry.with_index)
          fdt.PutInteger(entry.node, 'used', len(data))
          add_hash = fdt.GetBool(entry.node, 'add-hash')
          if len(directory) > 1 or add_hash:
            # Deprecate this: crbug.com/254311
            # In fact entry.with_index should be deprecated - it is not needed
            # since we can just look at the FDT. Ick.
            fdt.PutInteger(entry.node, '#address-cells', 1)
            fdt.PutInteger(entry.node, '#size-cells', 1)
            for key, item in directory.iteritems():
              fdt.PutIntList(entry.node + '/' + key, 'reg', item)
              hasher = hashlib.sha256()
              offset, size = item
              hasher.update(data[offset:offset + size])
              hash_value = hasher.digest()
              byte_count = struct.unpack('%dB' % len(hash_value), hash_value)
              fdt.PutBytes(entry.node + '/' + key, 'hash', byte_count)
              fdt.PutBool(entry.node + '/' + key, 'this-is-deprecated', True)
          if add_hash:
            hasher = hashlib.sha256()
            hasher.update(data)
            hash_value = hasher.digest()
            byte_count = struct.unpack('%dB' % len(hash_value), hash_value)
            fdt.PutBytes(entry.node, 'hash', byte_count)

  def CheckProperties(self):
    """Check that each entry has the properties that it needs.

    Entries with a 'key' use that to look up properties. We need to make
    sure that there is a property for that key. If not, then the entry will
    not be able to access the data it needs during the packing stage.

    Raises:
      ConfigError: The property for a required key is missing
    """
    for entry in self.entries:
      if entry.required and entry.key:
        if 'value' not in entry:
          entry.value = []
        for prop in entry.key.split(','):
          if not self.props.get(prop):
            raise ConfigError("%s: Requests property '%s' but we only "
                "have %s" % (entry.node, prop, self.props.keys()))
          entry.value.append(self.props[prop])

  def RequireAllEntries(self):
    """Mark all entries as required, to produce a full image."""
    for entry in self.entries:
      entry.required = True

  def GetMissingBlobs(self):
    """Returns a list of blobs that do not currently have data assigned.

    Some blobs may not yet have data assigned, ie. self.props[] does not
    contain a filename for one or more of the blob's data types. This
    function returns a list of nodes that still need to be processed.

    Returns:
      List of device tree nodes that have no data assigned. Each is a
      namedtuple with these members:
        node: Full path to device tree node
        key: Key name (e.g. exynos-bl2')
        params: List of [arameters to the node - the first element is the
            list of files within the blob, for example 'boot,dtb'
    """
    missing = []
    for entry in self.entries:
      if entry.required and isinstance(entry, EntryBlob):
        for prop in entry.key.split(','):
          if not self.props.get(prop):
            value = Value(entry.node, entry.key, entry.params)
            missing.append(value)
            break

    return missing

  def PackImage(self, tmpdir, output_path):
    """Pack the various components into a firmware image,

    You must call SetupFiles() and SelectFdt() first, to set things up. Then
    this function will create a firmware image for you.

    Args:
      output_path: Full path of file to contain the resulting image.

    Raises:
      PackError: If unable to fit something in the space available, or a
          required file or setup piece is missing.
    """
    self.tmpdir = tmpdir

    all_entries = self._CheckOverlap()
    image_used = 0

    # Set up a zeroed file of the correct size.
    with open(output_path, 'wb') as image:
      if all_entries:
        image.write('\0' * self.image_size)

      # Pack all the entriess.
      ifd = None
      for entry in self.entries:
        if not entry.required:
          self._out.Info("Section '%s' is not required, skipping" % entry.name)
          continue

        # Add in the info for the fmap.
        if type(entry) == EntryFmap:
          entry.SetEntries(base=0, image_size=self.image_size,
              entries=self.entries)
        elif type(entry) == EntryIfd:
          ifd = entry

        try:
          # First run any required tools.
          entry.RunTools(self.tools, self._out, self.tmpdir)
          if 'value' in entry:
            self._out.Notice("Pack '%s' into %s" % (', '.join(entry.value),
                entry.name))

          # Now read out the data
          data = entry.GetData()
          self._out.Debug('Entry: %s' % entry.name)
          self._out.Debug('Entry data: %s' % entry)
          self._out.Debug('Data size: %s bytes, at %#x' %
              (len(data), entry.offset))
          if len(data) > entry.size:
            raise PackError("Data for '%s' too large for area: %d/%#x >"
                " %d/%#x" % (entry.name, len(data), len(data), entry.size,
                entry.size))
          if entry.size:
            usage = len(data) * 100 / entry.size
          else:
            usage = 0
          self._out.Notice('Entry: %s, size %#x, data %#x, usage %d%%' %
              (entry.name, entry.size, len(data), usage))
          entry.used = len(data)
          image_used += entry.used

          image.seek(entry.offset)
          image.write(data)

        except PackError as err:
          raise ValueError('Packing error: %s' % err)

    # If the image contain an IFD section, process it
    if ifd:
      ifd.ProduceFinalImage(self.tools, self._out, self.tmpdir, output_path)

    self._out.Notice('Image size %#x, data %#x, usage %d%%' %
      (self.image_size, image_used, image_used * 100 / self.image_size))

  def _OutEntry(self, status, offset, size, name, fname):
    """Display a flash map entry.

    Args:
      status: Status character.
      offset: Byte offset of entry.
      size: Size of entry in bytes.
      name: Name of entry.
      fname: Filename of entry
    """
    indent = '' if status == '-' else ' '
    self._out.UserOutput('%s %08x  %08x  %s%-12s  %s' % (status, offset, size,
        indent, name, fname))

  def ShowMap(self):
    """Show a map of the final image."""
    self._out.UserOutput('Final Flash Map:')
    self._out.UserOutput('%s %8s  %8s  %-12s  %s' %
                         ('S', 'Start', 'Size', 'Name', 'File'))
    offset = 0
    for entry in self.entries:
      if not entry.ftype:
        status = '-'
      elif entry.required:
        status = 'P'
      else:
        status = '.'
      if offset != entry.offset:
        self._OutEntry('!', offset, entry.offset - offset, '<gap>', '')
      self._OutEntry(status, entry.offset, entry.size, entry.name,
                     entry.get('value', ''))
      if entry.ftype:
        offset = entry.offset + entry.size
      else:
        offset = entry.offset

def _Test():
  """Run any built-in tests."""
  import doctest
  assert doctest.testmod().failed == 0

def _PackOutput(msg):
  """Helper function to write output from PackFirmware (verbose level 2).

  This is passed to PackFirmware for it to use to write output.

  Args:
    msg: Message to display.
  """
  print msg

def main():
  """Main function for pack_firmware.

  We provide a way of packing firmware from the command line using this module
  directly.
  """
  parser = optparse.OptionParser()
  parser.add_option('-v', '--verbosity', dest='verbosity', default=1,
      type='int', help='Control verbosity: 0=silent, 1=progress, 3=full, '
      '4=debug')
  parser.add_option('-k', '--key', dest='key', type='string', action='store',
      help='Path to signing key directory (default to dev key)',
      default='##/usr/share/vboot/devkeys')
  parser.add_option('-d', '--dt', dest='fdt', type='string', action='store',
      help='Path to fdt file to use (binary ,dtb)', default='u-boot.dtb')
  parser.add_option('-u', '--uboot', dest='uboot', type='string',
      action='store', help='Executable bootloader file (U-Boot)',
      default='u-boot.bin')
  parser.add_option('-S', '--signed', dest='signed', type='string',
      action='store', help='Path to signed boot binary (U-Boot + BCT + FDT)',
      default='u-boot-fdt-signed.bin')
  parser.add_option('-g', '--gbb', dest='gbb', type='string',
      action='store', help='Path to Google Binary Block file',
      default='gbb.bin')
  parser.add_option('-o', '--outdir', dest='outdir', type='string',
      action='store', help='Path to directory to use for intermediate and '
      'output files', default='out')

  (options, _) = parser.parse_args(sys.argv)

  # Set up the output directory.
  if not os.path.isdir(options.outdir):
    os.makedirs(options.outdir)

  # Get tools and fdt.
  tools = Tools(options.verbosity)
  fdt = Fdt(tools, options.fdt)

  # Pack the firmware.
  pack = PackFirmware(_PackOutput, tools, options.verbosity)
  pack.SetupFiles(boot=options.uboot, signed=options.signed, gbb=options.gbb,
      fwid=tools.GetChromeosVersion(), keydir=options.key)
  pack.SelectFdt(fdt)
  out_fname = os.path.join(options.outdir, 'image.bin')
  pack.PackImage(options.outdir, out_fname)
  print 'Output binary is %s' % out_fname

if __name__ == '__main__':
  if sys.argv[1:2] == ["--test"]:
    _Test(*sys.argv[2:])
  else:
    main()
