#!/usr/bin/env python
from optparse import *
from time import time
from sys import stdout, stderr

conns  = ('serial', 'ipv6', 'ftdi')
parser = OptionParser()
parser.add_option('-a', '--address', dest='addr', type='int',
                  help='start reading at address', metavar='ADDR', default=0x00000000)
parser.add_option('-l', '--len', dest='len', type='int',
                  help='number of bytes to read', metavar='LEN', default=192000)
parser.add_option('-m', '--mac', dest='mac',
                  help='reset the mac addr')
parser.add_option('-k', '--key', dest='key',
                  help='reset the license key')
parser.add_option('-v', '--verbose', action='store_true', dest='verbose',
                  help='print send and received packets')
parser.add_option('-y', '--verify', action='store_true', dest='verify',
                  help='also verify after writing')
parser.add_option('-s', '--show', dest='show', action='store_true',
                  help='show mac address and license key')
parser.add_option('-e', '--erase', dest='erase', action='store_true',
                  help='erasing the flash after reading mac and license key')
parser.add_option('-c', '--connection', type='choice', dest='conn', default='serial', choices=conns[:-1],
                  help='connection implementation ('+",".join(conns[:-1])+') [default: %default]')
parser.add_option('-t', '--target', type='string', help='target for connection', dest='target')

(options, args) = parser.parse_args()

if options.conn=='serial':
    import con_serial
    bl = con_serial.SerialBootloader(options.target)
elif options.conn=='ipv6':
    import con_ipv6
    bl = con_ipv6.IPBootloader(options.target)
elif options.conn=='ftdi':
    import con_ftdi
    bl = con_ftdi.FtdiBootloader()
else:
    raise Exception('nahh')

if options.verbose: bl.isverbose = True

#
# Select the actions:
#
if options.show or options.erase:
    stdout.write("flash: %s %s\n"%(bl.flash_manufacturer, bl.flash_type))
    stdout.write("mac: 0x")
    for b in bl.read_mac(): stdout.write("%02x"%b)
    stdout.write(" license: 0x")
    for b in bl.read_license(): stdout.write("%02x"%b)
    stdout.write("\n")
    if options.erase: bl.erase_flash()

elif options.mac or options.key:
    if options.mac:
        bl.set_mac(options.mac)
        bl.write_mac()
    if options.key:
        bl.set_license(options.key)
        bl.write_license()

elif len(args)!=1:
    block,i,start = bl.preferedblocksize or 0xf0,0,time()
    for addr in xrange(options.addr, options.addr+options.len, block):
        for byte in bl.read_flash(addr, block):
            stdout.write("%c"%byte)

        if addr>((options.addr+options.len)/10.*i):
            stderr.write("%i%%.."%(i*10))
            i += 1

    kb,sec  = options.len/1000., (time()-start)
    stderr.write("done - %0.2f kb/s\n"%(kb/sec))

else:
    file = open(args[0], "rb")

    # read the file size
    file.seek(0, 2)
    size = file.tell()
    file.seek(0, 0)

    # start reading the file, 0x80 seems to be the only blocksize
    # working for the jennic bootloader with certain flashtypes
    block,i,start = bl.preferedblocksize or 0x80,0,time()
    data = file.read(block)
    addr = 0x00000000

    # erase_flash gets the mac and license key prior to doing
    # its opertation.
    bl.erase_flash()

    while len(data) != 0:
        bl.write_flash(addr, data)
        addr += len(data)
        data  = file.read(block)

        if addr>(size/10.*i):
            stderr.write("%i%%.."%(i*10))
            i += 1

    kb,sec  = size/1000., (time()-start)
    stderr.write("done - %0.2f kb/s "%(kb/sec))

    stderr.write("- writing mac address and key..")
    bl.write_mac()
    bl.write_license()
    bl.finish()
    stderr.write("done\n")

    if options.verify:
        raise Exception, "not implemented"

