#!/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,
      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 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()
