#!/usr/bin/python

#
# Copyright (c) 2007,2008,2009 MBARI
# MBARI Proprietary Information.  All Rights Reserved
#
# Usage:
# cat /tmp/test.bin | ./encode2Send.py test.bin
# 

import binascii, gzip, os, struct, sys, time

CHARS_PER_LINE = 256

if len(sys.argv) < 3:
  print >> sys.stderr, "Usage: %s sourceFile [targetFile] encodeKey" % sys.argv[0]
  sys.exit(1)

source = sys.argv[1]

if len(sys.argv) < 4:
  target = source
  encodeKey = sys.argv[2]
else:
  target = sys.argv[2]
  encodeKey = sys.argv[3]  
  
sourceFile = open( source, 'r' )
data = sourceFile.read()
sourceFile.close()

targetGz = target + ".gz"

gzFile = gzip.open(targetGz, 'wb')
gzFile.write(data)
gzFile.close()

gzFile = open(targetGz, 'r')
gzData = gzFile.read()
gzFile.close()
os.remove(targetGz)

doGz = len(gzData) + 15 < len(data)

if doGz:
  streamCmd = "| gunzip -f -d > %s"
  data = gzData
  print "Using gz"
else:
  streamCmd = "> %s"
  print "Not using gz"

stamp = struct.pack("<i",time.time())
crc = struct.pack("<i", binascii.crc32(data))
size = len(data)
sizeData = struct.pack("<i",size);
flags = 0x80
sizeLen = 4
if size >= 2**24:
    flags = flags | 0x04
elif size >= 2**16:
    flags = flags | 0x02
    sizeLen = 3
else:
    sizeLen = 2
zeroData = struct.pack("B", 0)

line = 0
sbd = "%s.%03d.sbd" % (os.path.basename(target), line) 
sbdSrc = sbd + ".src"
sbdSrcFile = open( sbdSrc, 'wb' )
sbdBytes = 0
sbdSrcFile.write(struct.pack("B", flags))
sbdBytes = sbdBytes + 1;
sbdSrcFile.write(stamp) 
sbdBytes = sbdBytes + 4;
sbdSrcFile.write(crc)
sbdBytes = sbdBytes + 4;
sbdSrcFile.write(sizeData[:sizeLen])
sbdBytes = sbdBytes + sizeLen;
sbdSrcFile.write( streamCmd )
sbdSrcFile.write(zeroData)
sbdBytes = sbdBytes + len(streamCmd) + 1;
sbdSrcFile.write( target )
sbdSrcFile.write(zeroData)
sbdBytes = sbdBytes + len(target) + 1;
bytesToSend = min(CHARS_PER_LINE-sbdBytes, size)
sbdSrcFile.write(data[:bytesToSend])
sbdSrcFile.close();
cmd_sbd = "bin/sbd -i %s -o %s %s" % (sbdSrc, sbd, encodeKey)
os.system(cmd_sbd)
offset = bytesToSend
os.remove(sbdSrc)

while size - offset > 0:
    flags = flags | 0x01
    line = line + 1
    sbd = "%s.%03d.sbd" % (os.path.basename(target), line) 
    sbdSrc = sbd + ".src"
    sbdSrcFile = open( sbdSrc, 'wb' )
    sbdBytes = 0
    sbdSrcFile.write(struct.pack("B", flags))
    sbdBytes = sbdBytes + 1;
    sbdSrcFile.write(stamp) 
    sbdBytes = sbdBytes + 4;
    offsetData = struct.pack("<i",offset);
    sbdSrcFile.write(offsetData[:sizeLen])
    sbdBytes = sbdBytes + sizeLen;
    bytesToSend = min(CHARS_PER_LINE-sbdBytes, size-offset)
    sbdSrcFile.write(data[offset:offset+bytesToSend])
    sbdSrcFile.close();
    cmd_sbd = "bin/sbd -i %s -o %s %s" % (sbdSrc, sbd, encodeKey)
    os.system(cmd_sbd)
    offset = offset + bytesToSend
    os.remove(sbdSrc)
