#!/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 writes a firmware image to a tegra-based board.

This utility uses a number of libraries for its activity.
"""

# Python imports
import optparse
import os
import sys

from fdt import Fdt
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.
  """
  tools.CheckTool('fdtput', 'dtc')
  tools.CheckTool('fdtget', 'dtc')

def _DoWriteFirmware(options, output, tools, update, verify, dest):
  """The main part of the cros_write_firmware code.

  This takes the supplied options and performs the firmware write.

  Args:
    options: Parser options.
    output: cros_output object to use.
    tools: Tools object to use.
    update: Use faster update algorithm rather then full device erase
    verify: Verify the write by doing a readback and CRC
  """
  _CheckTools(tools, options)
  tools.PrepareOutputDir(options.outdir, options.preserve)

  bundle = Bundle(tools, output)
  bundle.SetFiles(board=options.board, bct=options.bct,
      exynos_bl1=options.exynos_bl1, exynos_bl2=options.exynos_bl2)

  # Get the FDT from the image if possible.
  if not options.fdt:
    fdt_fname = tools.GetOutputFilename('fdt-from-image.dtb')
    fdt = Fdt(tools, fdt_fname)
    fdt.ExtractFromImage(options.image)
    options.fdt = fdt_fname
    if not options.board:
      bundle._board = fdt.GetString('/chromeos-config', 'board', 'none')
      if bundle._board == 'none':
        raise ValueError('Cannot obtain board type from FDTMAP')
      output.Notice("Using board from fdtmap: '%s'" % bundle._board)

  if options.use_defaults:
    bundle.CheckOptions()
  bundle.spl_source = options.spl_source
  # Set up the fdt and options that we want.
  fdt = bundle.SelectFdt(options.fdt, options.use_defaults)

  # Write it to the board.
  flasher = options.uboot_flasher
  if not flasher:
    flasher = bundle.uboot_fname
  file_list = bundle.GetFiles()
  write_firmware.DoWriteFirmware(output, tools, fdt, flasher,
      file_list, options.image, bundle, update, verify, dest,
      flasher_dest=options.flash_dest, servo=options.servo,
      method=options.method)


def main():
  """Main function for cros_bundle_firmware."""
  parser = optparse.OptionParser()
  parser.add_option('-b', '--board', dest='board', type='string',
      action='store', help='Board name to use (e.g. tegra2_kaen)')
  parser.add_option('-B', '--boot', dest='spl_source', type='string',
      action='store', help='Device for SPL to boot from (straps, spi, emmc)',
      default='straps')
  parser.add_option('--bl1', dest='exynos_bl1', type='string',
      action='store', help='Exynos preboot (BL1) file')
  parser.add_option('--bl2', dest='exynos_bl2', type='string',
      action='store', help='Exynos Secondary Program Loader (SPL / BL2) file')
  parser.add_option('-c', '--bct', dest='bct', type='string', action='store',
      help='Path to BCT file for flasher: only one can be given')
  parser.add_option('-d', '--dt', dest='fdt', type='string', action='store',
      help='Path to fdt source .dts or binary blob .dtb file for flasher')
  parser.add_option('-D', '--nodefaults', dest='use_defaults',
      action='store_false', default=True,
      help="Don't select default filenames for those not given")
  parser.add_option('-f', '--full-erase', dest='full_erase',
      action='store_true', help='Erase entire flash before writing (slow)')
  parser.add_option('-F', '--flash', dest='flash_dest', type='string',
      action='store', help='Create a flasher to flash the device (spi, mmc)')
  parser.add_option('-i', '--image', dest='image', type='string',
      action='store', help='Firmware image to write')
  parser.add_option('-I', '--includedir', dest='includedirs', type='string',
      action='append', help='Include directory to search for files')
  parser.add_option('-M', '--method', type='string', default='tegra',
      action='store', help='Set USB flash method (tegra/exynos)'
      'output files')
  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 even if option -O is not given')
  parser.add_option('--servo', type='string', default='any',
        action='store', help='Servo to use (none, any, or port number)')
  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 board's u-boot.bin)")
  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('-V', '--verify', dest='verify', action='store_true',
      help='Verify flash after writing')
  parser.add_option('-w', '--write', dest='write', type='string',
      action='store', default='usb', help='Write firmware to device (usb, sd)')
  (options, args) = parser.parse_args(sys.argv)
  if not options.image and len(args) > 1:
    options.image = args[1]
    del args[1]
  if not options.image:
    parser.error('Please use --image to specify a firmware image to flash');
  if len(args) > 1:
    parser.error("Unrecognized arguments '%s'" % ' '.join(args[1:]))

  with cros_output.Output(options.verbosity) as output:
    with Tools(output) as tools:
      if options.includedirs:
        tools.search_paths += options.includedirs
      try:
        _DoWriteFirmware(options, output, tools, not options.full_erase,
                         options.verify, dest=options.write)
      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 _Test():
  """Run any built-in tests."""
  import doctest
  assert doctest.testmod().failed == 0

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