#!/usr/bin/python
import time, os, LGI;
import math, sys;
from shutil import rmtree

# FUNCTION ENDS HERE
#----------------------------------------------------------------------------------------------------------

def check_finished(CURRENT_DIRECTORY, Client, functional, millerindex ):
	print "Entering check_finished function...."
	print "Current date & time " + time.strftime("%c")

	LIST_FINISHED  = Client.GetJobList( Application = "vasp535", State = "finished", Limit=1024);
	N_FINISHED = LIST_FINISHED[ 'LGI' ][ 'response' ][ 'number_of_jobs' ];

	if (N_FINISHED > 1):
		#for JOB_FINISHED in LIST_FINISHED[ 'LGI' ][ 'response' ][ 'job' ][ : ][ 'job' ]:
		for job_num in range(0, N_FINISHED):
 
			#GET THE JOB ID  
			JOB_FINISHED   = LIST_FINISHED[ 'LGI' ][ 'response' ][ 'job' ][ job_num ][ 'job' ];                   
			job_id         = JOB_FINISHED[ 'job_id' ]
			job_specifics  = JOB_FINISHED[ 'job_specifics' ]
			project        = job_specifics[ 'project' ]

			if ( project == "NN" ):
				repository_url = job_specifics[ 'repository_url' ] 
				folder         = job_specifics[ 'foldername' ]
				func           = job_specifics[ 'functional' ]
				mill           = job_specifics[ 'millerindex' ]

				#only do something if the job is from batch 
				if ( func == functional ) and ( str(mill) == millerindex ):
					#TRANSFER FILES
					#CHANGE THE DIRECTORY  
					os.chdir("LGI_OUTPUT");
					#MAKE A NEW DIRECTORY
					if os.path.isdir( folder ): rmtree( folder )

					os.mkdir("%s" %(folder));
					os.chdir("%s" %(folder));
					#TRANFER FILE
					#Client.LGI_filetransfer download repository_url OUTCAR OSZICAR POSCAR vasprun.xml ;
					print "downloading: ", repository_url
					FileTransferClient = LGI.LGI_Client( URL = repository_url );
					FileTransferClient.DownLoadFiles( [ "OUTCAR", "OSZICAR", "POSCAR", "vasprun.xml" ], "./" );
					print "deleting job nr ", job_id
					Client.DeleteJob( job_id );
					del FileTransferClient;
					#GO BACK TO WORKING DIRECTORY
					os.chdir(CURRENT_DIRECTORY);

# FUNCTION ENDS HERE
#----------------------------------------------------------------------------------------------------------

#ASK FOR THE CURRENT DIRECTORY
CURRENT_DIRECTORY = os.getcwd()

project    = "NN"
functional = "PBEa57-DF2"
Queue      = "long"
maxwalltime= "72:00:00"
maxram     = "55"
NCores     = "16"
Client     = LGI.LGI_Client()

Ntot = 10000
layers = 5
supercellx = 1
supercelly = 3
mil_h = 9
mil_k = 7
mil_l = 7

#LGI allows 2500 jobs to be in the queue per VASP version for all users combined: includes running, queued, and finished
MAX_NUM_JOBS  = 1000;

#os.mkdir("LGI_OUTPUT");
COUNT = 0
COUNTFINISH = 0

restart_file = "restart_file_{0:d}{1:d}{2:d}".format( mil_h, mil_k, mil_l )
start_val = 0
#check whether the restart_file exists
# and if it exists, then read the start value

if os.path.isfile(restart_file) :
	data_list = open(restart_file, "r").readline()
	start_val = int(data_list) + 1	# plus 1 as this is the geometry we want to submit, the restart file contains the last submitted geometry
	print "RESTART FILE FOUND"
else :
	start_val = 0
	print "NO RESTART_FILE, START FROM SCRATCH"
print "START VALUE IS ",  start_val, "\n"

foldername = "LGI_OUTPUT/{:d}{:d}{:d}-{:d}x{:d}-{:d}L".format(mil_h, mil_k, mil_l, supercellx, supercelly, layers)
if not os.path.isdir( foldername ):
	os.mkdir( foldername )

start_val = 0

#start submit loop
for idx in range(start_val, Ntot):
	#folder name we are going to give to job_specifics together with functional
	foldername = "{:d}{:d}{:d}-{:d}x{:d}-{:d}L/{:0>6d}".format(mil_h, mil_k, mil_l, supercellx, supercelly, layers, idx)

	print(foldername)

	if os.path.isdir( "LGI_OUTPUT/" + foldername ):
		print('WARNING: folder already exists')
		continue
#		exit(1)

	if idx < 2000:
		Zmin = 2.0
		Zmax = 8.0
		rmin = 0.5
		rmax = 1.5
		surface_motion = False
	elif idx > 1999 and idx < 10000:
		Zmin = 0.3
		Zmax = 2.5
		rmin = 0.5
		rmax = 2.5
		surface_motion = False
	else:
		print('WARNING: Z and r are not defined')
		exit(1)

	os.system( './slab_H2-poscar.py {:d} {:d} {:d} {:d} {:d} {:d} {:f} {:f} {:f} {:f} {:s}'.format( layers, supercellx, supercelly, mil_h, mil_k, mil_l, Zmin, Zmax, rmin, rmax, str(surface_motion) ) )

	# FIRST: ASK LGI HOW MANY JOBS ARE RUNNING
	#        AND HOW MANY JOBS ARE QUEUED
	# IF THE NUMBER OF QUEUED JOBS IS LARGER THEN MAX_NUM_QUEUED_JOB
	# THEN FALL ASLEEP, OTHERWISE CONTINUE WITH SUBMITTING JOBS
	CONTINUE_VAR = 1 ;
	while CONTINUE_VAR == 1 :
		LIST_QUEUED  = Client.GetJobList( Application = "vasp535", State = "queued", Limit=0 );
		LIST_RUNNING = Client.GetJobList( Application = "vasp535", State = "running", Limit=0);
		N_QUEUED     = LIST_QUEUED[ 'LGI' ][ 'response' ][ 'number_of_jobs' ] ;
		N_RUNNING    = LIST_RUNNING[ 'LGI' ][ 'response' ][ 'number_of_jobs' ];
		print "queued:", N_QUEUED, "running: ", N_RUNNING
        
		#Check if not too many jobs
		if (N_QUEUED + N_RUNNING < MAX_NUM_JOBS ):
			CONTINUE_VAR = 0
		else:        
			time.sleep(600)

	#IF THERE ARE ABORTED JOBS THEN DELETE THEM
	LIST_ABORTED  = Client.GetJobList( Application = "vasp535", State = "aborted", Limit=1024);
	N_ABORTED = LIST_ABORTED[ 'LGI' ][ 'response' ][ 'number_of_jobs' ];
	if N_ABORTED > 1:
		for job_num in range(0, N_ABORTED):
			JOB_ABORTED = LIST_ABORTED[ 'LGI' ][ 'response' ][ 'job' ][ job_num ][ 'job' ];
			job_id = JOB_ABORTED[ 'job_id' ];
			job_specifics = JOB_ABORTED[ 'job_specifics' ];
			repository_url = job_specifics[ 'repository_url' ] ;
			Client.DeleteJob( job_id );

	## SECOND: CREATE AND SUBMIT A JOB  
	# you can add your own keys to the job by adding to job specifics <key> value </key>
	JOB = Client.SubmitJob( 
	Application     = "vasp535",
	TargetResources = "mark@octo.wks.gorlaeus.net,mark@erc1.wks.gorlaeus.net,mark@erc2.wks.gorlaeus.net,mark@epyc.tc.lic.leidenuniv.nl",
	#TargetResources = "mark@octo.wks.gorlaeus.net,mark@erc1.wks.gorlaeus.net,mark@erc2.wks.gorlaeus.net,mark@epyc.tc.lic.leidenuniv.nl,somers@cartesius.surfsara.nl",
	FileList        = [ "./INPUTS/INCAR", "./INPUTS/vdw_kernel.bindat", "./INPUTS/POTCAR", "./POSCAR", "./INPUTS/KPOINTS" ], 
	#now job specifics -- here we can give specifiers for the job in xml format
	JobSpecifics    = "<functional> {0} </functional> <foldername> {1} </foldername> <walltime> {2} </walltime> <mem> {3} </mem> <project> {4} </project> <Queue> {5} </Queue> <cpus> {6} </cpus> <IDnumber> {7} </IDnumber> <millerindex> {8} </millerindex>".format(functional, foldername, maxwalltime, maxram, project, Queue, NCores, idx, str(mil_h)+str(mil_k)+str(mil_l)) )

	COUNT = COUNT + 1;         
	print " Number of Jobs submitted ", COUNT

	#write restart file
	fout_file = open(restart_file, "w")
	fout_file.write("{:d}".format( idx ))
	fout_file.close()

	#now check for finished jobs
	check_finished(CURRENT_DIRECTORY, Client, functional, str(mil_h)+str(mil_k)+str(mil_l) )

print
print "entering retrieval loop"
CONTINUE_VAR = 1 ;
while CONTINUE_VAR == 1 :
	check_finished(CURRENT_DIRECTORY, Client, functional, str(mil_h)+str(mil_k)+str(mil_l) )
	print "Going to sleep ......"
	time.sleep(1800);     


