#!/usr/bin/python

import sys, getopt, hashlib, uuid, os
from pprint import pprint
sys.path.append('/usr/local/bin/thrift-ice-py')
 
from ice import Ice
from ice.ttypes import *
 
from thrift import Thrift
from thrift.transport import TSocket
from thrift.transport import TTransport
from thrift.protocol import TBinaryProtocol

#
# https://stackoverflow.com/questions/1131220/get-md5-hash-of-big-files-in-python
#
def md5sum(filename):
    md5 = hashlib.md5()
    with open(filename, 'rb') as f:
        for chunk in iter(lambda: f.read(128 * md5.block_size), b''):
            md5.update(chunk)
    return md5.hexdigest()

def main(argv):

  sFile = stFileInfo()

  try:
    opts, args = getopt.getopt(sys.argv[1:],"hlu:dca:su:fw:", ["help", "list", "upload=", "download", "copy", "ack=", "status", "uuid=", "fullhistory", "windowhistory="])
  except getopt.GetoptError as err:
    print str(err)
    Usage()
    sys.exit(2)
  for opt, arg in opts:
    if opt in ("-l", "--list"):
       FTListSessions()
       sys.exit()
    elif opt in ("-u", "--upload"):
       #user passed in a fully qualified path... or not fix it for them
       if arg[0] == "/":
           sFile.path=arg
       else:
           sFile.path=os.getcwd() + "/" + arg

       #get md5 of file, this is super memory inefficient... cleanup!
       sFile.md5 = md5sum(sFile.path)
       sFile.size = os.path.getsize(sFile.path)

       #split the full file/path apart to get the name
       sFile.name = sFile.path[sFile.path.rfind("/")+1:]
       #sFile.path = sFile.path[:sFile.path.rfind("/")+1]

       sFile.type = eFTType.ENGINEERING

       FTUpload(sFile)
       sys.exit()
    elif opt in ("-d", "--download"):
       FTDownload(sFile.id)
       sys.exit()
    elif opt in ("-c", "--copy"):
       FTCopy(sFile.id)
       sys.exit()
    elif opt in ("-a", "--ack"):
       FTAck(sFile.id, arg)
       sys.exit()
    elif opt in ("-s", "--status"):
       FTStatus(sFile.id)
       sys.exit()
    elif opt in ("-f", "--fullhistory"):
       FTHistory()
       sys.exit()
    elif opt in ("-w", "--windowhistory"):
       FTHistoryWindow(arg)
       sys.exit()
    elif opt in ("-u", "--uuid"):
       if arg == "auto":       
          sFile.id = str(uuid.uuid4())
       else:
          sFile.id = arg     
    elif opt in ("-h", "--help"):
      Usage()
      sys.exit()
    else:
      Usage()
      sys.exit(2)

def FTHistoryWindow( startDate):
  try:
    transport = TSocket.TSocket('127.0.0.1', 9090)
    transport = TTransport.TBufferedTransport(transport)
    protocol = TBinaryProtocol.TBinaryProtocol(transport)
    client = Ice.Client(protocol)
    transport.open()
 
    pprint(client.FT_GetHistoryTime(startDate,""))
 
    transport.close()
 
  except Thrift.TException, tx:
    print str(tx)
    
def FTHistory():
  try:
    transport = TSocket.TSocket('127.0.0.1', 9090)
    transport = TTransport.TBufferedTransport(transport)
    protocol = TBinaryProtocol.TBinaryProtocol(transport)
    client = Ice.Client(protocol)
    transport.open()
 
    pprint(client.FT_GetHistoryIndex(0,0))
 
    transport.close()
 
  except Thrift.TException, tx:
    print str(tx)

def FTListSessions():
  try:
    transport = TSocket.TSocket('127.0.0.1', 9090)
    transport = TTransport.TBufferedTransport(transport)
    protocol = TBinaryProtocol.TBinaryProtocol(transport)
    client = Ice.Client(protocol)
    transport.open()
 
    pprint(client.FT_GetActiveSessions())
 
    transport.close()
 
  except Thrift.TException, tx:
    print str(tx)

def FTUpload( fileinfo ):
  try:
    transport = TSocket.TSocket('127.0.0.1', 9090)
    transport = TTransport.TBufferedTransport(transport)
    protocol = TBinaryProtocol.TBinaryProtocol(transport)
    client = Ice.Client(protocol)
    transport.open()

    print "Uploading-"
    print "ID: " + fileinfo.id 
    print "Path: " + fileinfo.path
    print "Name: " + fileinfo.name
    print "MD5: " + fileinfo.md5
    print "Size " + str(fileinfo.size)
    
    print client.FT_UploadFile(fileinfo)
 
    transport.close()
 
  except Thrift.TException, tx:
    print str(tx)

def FTDownload ( uuid ):
  try:
    transport = TSocket.TSocket('127.0.0.1', 9090)
    transport = TTransport.TBufferedTransport(transport)
    protocol = TBinaryProtocol.TBinaryProtocol(transport)
    client = Ice.Client(protocol)
    transport.open()
 
    sDLFile = stDownloadFileInfo()
    sDLFile.id = uuid
    sDLFile.name = "N/A"
    sDLFile.type = 0

    print client.FT_DownloadFile( sDLFile )
 
    transport.close()
 
  except Thrift.TException, tx:
    print str(tx)

def FTCopy( uuid ):
  try:
    transport = TSocket.TSocket('127.0.0.1', 9090)
    transport = TTransport.TBufferedTransport(transport)
    protocol = TBinaryProtocol.TBinaryProtocol(transport)
    client = Ice.Client(protocol)
    transport.open()
 
    print client.FT_CopyFile(uuid)
 
    transport.close()
 
  except Thrift.TException, tx:
    print str(tx)

def FTStatus( uuid ):
  try:
    transport = TSocket.TSocket('127.0.0.1', 9090)
    transport = TTransport.TBufferedTransport(transport)
    protocol = TBinaryProtocol.TBinaryProtocol(transport)
    client = Ice.Client(protocol)
    transport.open()

    print client.FT_GetStatus(uuid)
 
    transport.close()
 
  except Thrift.TException, tx:
    print str(tx)

def FTAck( uuid , ack ):
  try:
    transport = TSocket.TSocket('127.0.0.1', 9090)
    transport = TTransport.TBufferedTransport(transport)
    protocol = TBinaryProtocol.TBinaryProtocol(transport)
    client = Ice.Client(protocol)
    transport.open()
 
    if ack == "cancel":
        print client.FT_Ack(uuid, eFTAckType.CANCEL)

    if ack == "complete":
        print client.FT_Ack(uuid, eFTAckType.COMPLETE)
 
    transport.close()
 
  except Thrift.TException, tx:
    print str(tx)

def Usage():
    print 'ice-ft --uuid=[auto|UUID] [option]'
    print '   --list                  Lists active transfers'
    print '   --upload=[path]         Uploads file to server'
    print '   --download              Downloads UUID from server (not impl)'
    print '   --copy                  Returns info to access downloaded file'
    print '   --ack=[complete|cancel] Acknowledges transfer'
    print '   --status                Get status of transfer'
    print '   --fullhistory           Show transfer history'
    print '   --windowhistory=[TIME]  Get history from time [yyyy-MM-dd HH:mm:ss]'

if __name__ == "__main__":
   main(sys.argv[1:])
