#!/usr/bin/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.

"""This utility builds a firmware image for a tegra-based board.

This utility uses a number of libraries for its activity.

Hint: in order to run this outside the chroot you will need the following
from the chroot:

  /usr/bin:
    bmpblk_utility
    gbb_utility
    cbootimage
    vbutil_firmware
    dtget
    dtput

  /usr/lib:
    liblzma.so.0*
    libyaml-0.so.1*

"""

# Python imports
import optparse
import os
import sys

# Add the path to our own libraries
base = os.path.dirname(sys.argv[0])
sys.path.append(base)
sys.path.append(os.path.join(base, 'lib'))

from fdt import Fdt
from pack_firmware import PackFirmware
import write_firmware
from bundle_firmware import Bundle
import cros_output
from tools import Tools
from tools import CmdError

def _CheckTools(tools, options):
  """Check that all required tools are present.

  This just does a simple presence test on the external tools we thing we
  might need.

  Args:
    tools: Tools object to use to check tools.
    Options: Command line options provided.

  Raises:
    CmdError if a required tool is not found.
  """
  if options.write:
    tools.CheckTool('nvflash')
  tools.CheckTool('dtput', 'dtc')
  tools.CheckTool('dtget', 'dtc')

def _DoBundle(options, output, tools):
  """The main part of the cros_bundle_firmware code.

  This takes the supplied options and performs the firmware bundling.

  Args:
    options: Parser options.
    output: cros_output object to use.
    tools: Tools object to use.
  """
  _CheckTools(tools, options)
  tools.PrepareOutputDir(options.outdir, options.preserve)

  bundle = Bundle(tools, output)
  bundle.SetDirs(keydir=options.key)
  bundle.SetFiles(board=options.board, uboot=options.uboot, bct=options.bct,
                  bmpblk=options.bmpblk, coreboot=options.coreboot,
                  postload=options.postload, seabios=options.seabios)
  bundle.SetOptions(small=options.small)

  try:
    # Set up the fdt and options that we want.
    fdt = bundle.SelectFdt(options.fdt)
    bundle.SetBootcmd(options.bootcmd, options.bootsecure)
    bundle.AddConfigList(options.add_config_str)
    bundle.AddConfigList(options.add_config_int, use_int=True)

    out_fname = bundle.Start(options.hardware_id, options.output)

    # Write it to the board if required.
    if options.write:
      flasher = options.uboot_flasher
      if not flasher:
        flasher = bundle.uboot_fname
      text_base = bundle.CalcTextBase('flasher ', fdt, flasher)
      write_firmware.DoWriteFirmware(output, tools, fdt, flasher,
          bundle.bct_fname, out_fname, text_base)

  except (CmdError, ValueError) as err:
    # For verbosity 4 we want to display all possible information
    if options.verbosity >= 4:
      raise
    else:
      output.Error(str(err))
      sys.exit(1)

def main():
  """Main function for cros_bundle_firmware."""
  parser = optparse.OptionParser()
  parser.add_option('--add-config-str', dest='add_config_str', type='string',
      nargs=2, action='append', help='Add a /config string to the U-Boot fdt')
  parser.add_option('--add-config-int', dest='add_config_int', type='string',
      nargs=2, action='append', help='Add a /config integer to the U-Boot fdt')
  parser.add_option('-b', '--board', dest='board', type='string',
      action='store', help='Board name to use (e.g. tegra2_kaen)',
      default='tegra2_seaboard')
  parser.add_option('--bootcmd', dest='bootcmd', type='string',
      help='Set U-Boot boot command')
  parser.add_option('--bootsecure', dest='bootsecure',
      default=False, action='store_true',
      help='Boot command is simple (no arguments) and not interruptible')
  # TODO(sjg): Support multiple BCT files
  # TODO(sjg): Support source BCT files
  parser.add_option('-c', '--bct', dest='bct', type='string', action='store',
      help='Path to BCT source file: only one can be given')
  # TODO(sjg): Support source FDT files
  parser.add_option('-d', '--dt', dest='fdt', type='string', action='store',
      help='Path to fdt binary blob .dtb file to use')
  parser.add_option('-I', '--hwid', dest='hardware_id', type='string',
      action='store', help='Hardware ID string to use')
  parser.add_option('-B', '--bmpblk', dest='bmpblk', type='string',
      action='store', help='Bitmap block to use')
  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('-o', '--output', dest='output', type='string',
      action='store', help='Filename of final output image')
  parser.add_option('-O', '--outdir', dest='outdir', type='string',
      action='store', help='Path to directory to use for intermediate and '
      'output files')
  parser.add_option('-p', '--preserve', dest='preserve', action='store_true',\
      help='Preserve temporary output directory')
  parser.add_option('-P', '--postload', dest='postload', type='string',
      action='store', help='Path to post-load portion of U-Boot '
      '(u-boot-post.bin)')
  parser.add_option('-s', '--small', dest='small', action='store_true',
      help='Create/write only the signed U-Boot binary (not the full image)')
  parser.add_option('-S', '--seabios', dest='seabios', type='string',
        action='store', help='Legacy BIOS (SeaBIOS)')
  parser.add_option('-u', '--uboot', dest='uboot', type='string',
      action='store', help='Executable bootloader file (U-Boot)')
  parser.add_option('-U', '--uboot-flasher', dest='uboot_flasher',
      type='string', action='store', help='Executable bootloader file '
      '(U-Boot) to use for flashing (defaults to the same as --uboot)')
  parser.add_option('-C', '--coreboot', dest='coreboot', type='string',
      action='store', help='Executable lowlevel init file (coreboot)')
  parser.add_option('-v', '--verbosity', dest='verbosity', default=1,
      type='int', help='Control verbosity: 0=silent, 1=progress, 3=full, '
      '4=debug')

  # TODO(sjg): Move this into cros_write_firmware
  parser.add_option('-w', '--write', dest='write', action='store_true',
      default=False, help='Write firmware to SPI flash with USB A-A cable')
  (options, args) = parser.parse_args(sys.argv)

  with cros_output.Output(options.verbosity) as output:
    with Tools(output) as tools:
      _DoBundle(options, output, tools)


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

if __name__ == '__main__':
  # If first argument is --test, run testing code.
  if sys.argv[1:2] == ["--test"]:
    _Test(*sys.argv[2:])
  else:
    main()
