#!python

from __future__ import print_function
#from concurrent import futures
from pycpsw import *
import sys
import os
import datetime
import shutil
import time

MAX_WORKERS = 8

def prog():
	sys.excepthook = exceptionHandler
	import numpy as np

	base_dir = '/data/cpu-li28-hp01/data/'
	#description = """LI28-2 in accel mode
	#Rack doors open

	topDev = 'NetIODev'
	
	# setup and load config
	h = Hub.loadYamlFile( yaml_top, topDev )
	p = Path.create( h )
	p_mmio = p.findByName('mmio')
	
	try:
		 yaml_config
		p_mmio.loadConfigFromYamlFile( yamlConfig )
	except:
		pass
	
	
	# create stream interfaces
	streams = []
	for i in range(0, 8):
		name = "Stream" + str( i )
		path = p.findByName( name )
		strm = Stream.create( path )
		streams.append( (name, strm) )
	
	
	# command to trigger daq
	cmd   = Command.create( p.findByName('mmio/AmcCarrierMrEth/TrigDaq') )
	init0 = Command.create( p_mmio.findByName('AmcCarrierMrEth/AmcCarrierCore/AmcCarrierBsa/BsaWaveformEngine[0]/WaveformEngineBuffers/Initialize') )
	init1 = Command.create( p_mmio.findByName('AmcCarrierMrEth/AmcCarrierCore/AmcCarrierBsa/BsaWaveformEngine[1]/WaveformEngineBuffers/Initialize') )
	armDaq0 = Command.create( p_mmio.findByName('AmcCarrierMrEth/AmcCarrierMrLlrfApp/DaqMuxV2[0]/ArmHwTrigger') )
	armDaq1 = Command.create( p_mmio.findByName('AmcCarrierMrEth/AmcCarrierMrLlrfApp/DaqMuxV2[1]/ArmHwTrigger') )
	autoArm = ScalVal.create( p_mmio.findByName('AmcCarrierMrEth/AmcCarrierMrLlrfApp/DaqMuxV2/TriggerHwAutoRearm' ) )
	
	
	endAddr = ScalVal.create( p_mmio.findByName('AmcCarrierMrEth/AmcCarrierCore/AmcCarrierBsa/BsaWaveformEngine/WaveformEngineBuffers/EndAddr') )
	startAddr = ScalVal.create( p_mmio.findByName('AmcCarrierMrEth/AmcCarrierCore/AmcCarrierBsa/BsaWaveformEngine/WaveformEngineBuffers/StartAddr') )
	daqBufferSize = ScalVal.create( p_mmio.findByName('AmcCarrierMrEth/AmcCarrierMrLlrfApp/DaqMuxV2/DataBufferSize') )
	
	sAddr = np.array([0x0, 0x20000000, 0x40000000, 0x60000000, 0x80000000, 0xA0000000, 0xC0000000, 0xE0000000])
	eAddr = sAddr + 4*daq_size

	expected = daq_size*4
	
	# setup Bsa/DaqMux for appropriate buffer size
	endAddr.setVal( eAddr )
	startAddr.setVal( sAddr )
	daqBufferSize.setVal( daq_size )
	
	
	
	# get numpy buffer, will use to store stream data
	buf = np.getbuffer(np.zeros(daq_size*4), 0, daq_size*4)
	dt = np.dtype('uint16')
	
	init0.execute()
	init1.execute()

	date =  datetime.datetime.now().strftime("%Y%m%d-%H%M%S") 
	armDaq0.execute()	
	armDaq1.execute()	
#	
	for i in range(shots):
#		date =  datetime.datetime.now().strftime("%Y%m%d-%H%M%S") 
		directory = base_dir + date + "_" + str(i) + "/"
		try:
			os.mkdir( directory )
		except OSError, e:
			if e.errno != 17:
				raise  # This was not a "directory exist" error...
		
		with open( directory + 'description.txt', 'w' ) as desc:
			desc.write( description )
		
		shutil.copyfile( yamlConfig, directory + 'dumpConfig.yaml' )
		
		# trigger daq
		#cmd.execute()
		amcc_dump = directory + 'amcc_dump.txt'
		amcc_library = 'export LD_LIBRARY_PATH=/home/laci/cpu-li28-hp01/IPMC/lib64/:$LD_LIBRARY_PATH; '
		amcc_bin = 'export PATH=/home/laci/cpu-li28-hp01/IPMC/bin/x86_64-linux-dbg/:$PATH; '
		amcc_cmd = amcc_library + amcc_bin + 'amcc_dump --all shm-li28-hp01/2 > ' + directory + 'amcc_dump.txt'
		os.system(amcc_cmd)
	
		# arm HW triggers
		armDaq0.execute()	
		armDaq1.execute()	
	
		for n, s in streams:
			nelms = s.read( buf, 3000000 )
			#print( n + ": " + str( nelms ) )
			if nelms != expected:
				print("Warning ", exptected, " bytes expected, ", nelms, "bytes recieved")
			with open( directory + n + ".bin", 'wb' ) as strm:
	        		strm.write( buf )

		time.sleep(t)

        print('Run complete, data at: ',base_dir,date,'_<...>')

def read_save_stream(stream, buffer, timeout, filename):
	nelms = stream.read( buf, 500000 )
	save_stream( buf, filename )

def save_stream(data, filename):
	with open( filename, 'wb' ) as fp:
		fp.write( data )
def exceptionHandler(exception_type, exception, traceback):
	pass
    # print "%s: %s" % (exception_type.__name__, exception)


def usage(progname):
	print('Usage: ', progname, ' [-d <description>] [-s <size>] [-t <time>] [-n <number>]')
        print('    -d <description>: description of current run')
        print('    -s <size>       : daq size, number of points to take (default 0x30000)')
        print('    -t <time>       : time between shots (seconds) (default 0)')
        print('    -n <number>     : number of shots to take (default 10)')

if __name__ == "__main__":
        import getopt
        try:
                optlist, args = getopt.getopt(sys.argv[1:], 'hs:d:t:n:f:c:',
                        ['help', 'size=', 'delay=, number='])
        except getopt.GetoptError, err:
                print(str(err))
                usage(sys.argv[0])
                sys.exit(2)
        for o,arg in optlist:
                if o in ('-h', '--help'):
                        usage(sys.argv[0])
                        sys.exit()
                elif o in ('-s', '--size'):
                        daq_size = int(arg)
                elif o in ('-d', '--desription'):
                        description = str(arg)
                elif o in ('-t', '--time'):
                        t = int(arg)
                elif o in ('-n', '--number'):
                        shots = int(arg)
                elif o in ('-f', '--yaml'):
                        yam1_top    = str(arg)
                elif o in ('-c', '--config'):
                        yam1_config = str(arg)

	sys.excepthook = exceptionHandler

	try:
		description
	except NameError:
		description = ""

	try:
		t
	except NameError:
		t = int(0)

	try:
		daq_size
		daq_size = daq_size/2
		daq_size = int((daq_size)/4096)*4096
	except NameError:
		daq_size = 0x18000

	try:
		shots
	except NameError:
		shots = int(10)
	try:
		yaml_top
	except NameError:
		yaml_top = '/u/cd/mdewart/Desktop/md/000TopLevel.yaml' 

	prog() 
