#!/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)
  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,
      flash_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 not options.board:
    parser.error('Please use --board to specify the board type 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()
