#!/usr/bin/python

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

import binascii, 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)

if len(sys.argv) < 4:
  target = sys.argv[1]
  encodeKey = sys.argv[2]
  source = os.path.join(os.path.dirname(target),".svn","text-base",os.path.basename(target)+".svn-base")
  print "source = " + source
else:
  source = sys.argv[1]
  target = sys.argv[2]
  encodeKey = sys.argv[3]

diff = target + ".diff"
targetGz = target + ".diff.gz"

os.system("diff -e %s %s > %s" %( source, target, diff ) )
os.system("echo w >> %s" %( diff ) )
os.system("gzip -n -f %s" %( diff ) )

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

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)

streamCmd = "| gunzip -f -d | cat `cp %s %%s` | vim -e %%s" % (source)

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)
