#!/usr/bin/env python
#################################################################################################################
# AUTHOR: KANNAN MASILAMANI, NIKHIL ANAND
#################################################################################################################
#IMPORTANT NOTE: DON'T MODIFY THIS FILE: JUST USE IT AS TEMPLATE TO CREATE YOUR OWN PYTHON SCRIPT
#################################################################################################################

#################################################################################################################

##----------  IMPORT LIBRARIES  -------------------------------------------------------------------------------##
import sys
import re
import logging
import subprocess
from subprocess import call
import os
import string
from itertools import *
##-------------------------------------------------------------------------------------------------------------##


##----------  FUNCTIONS  ------ ------------------------ ------------------------------------------------------##

# generates a temporary script which would generate scripts from given template file    
def genscript(filename,lua_file,template,parameters,values,path_lib,s):
  st=''
#  print "##--------------------------------------------------------------------------------##"
  if s == 'lua':
     filename = filename+'.lua'
     print "Generating Lua Script: %s"%filename
  else:
     st = 'path_to_exec'+'=\''+path_to_exec+'\','+'argument'+'=\''+lua_file+'.lua\''+','
     filename = filename+'.job'
     print "Generating job Script: %s"%filename

  
  for i in range(len(parameters)):
    if not isinstance(parameters[i],(tuple)):
      if i==(len(parameters)-1):
        st=st+parameters[i]+'=\''+str(values[i])+'\''
      else:
        st=st+parameters[i]+'=\''+str(values[i])+'\','
    else:
      for ii in range(len(parameters[i])):
        if i==(len(parameters[i])-1):
          st = st + parameters[i][ii]+'=\''+values[i][ii]+'\''
        else:
          st = st + parameters[i][ii]+'=\''+values[i][ii]+'\','

  script=open('script.py','w')
  script.write("#!/usr/bin/env python\n")
  script.write("import sys\n")
  script.write("import logging\n")
  script.write("sys.path[:0]=[\"")
  script.write("%s"%path_lib)
  script.write("\"]\n")
  script.write("import pyratemp as pyratemplate\n")
  script.write("logfile = open(\"%s\",\"w\")\n"%filename)
  script.write("mytemplate = pyratemplate.Template(filename=\"%s\")\n"%template)
  script.write("logfile.write(mytemplate(%s))\n"%st)
  script.write("logfile.close()")
  script.close()  
  success=subprocess.call("python script.py", shell=True)
  if success==1:
    print "\n\n!!! ERROR: run_simulation will now exit:\n"
    print"CHECK IF LUA TEMPLETE FILE HAS MORE PARAMETERS TO CHANGE THAN SPECIFIED IN params.list "
    print"IN CASE YOU JUST WANT JOBSCRIPTS PUT A TEMPLATE FILE IN config/ WITHOUT ${ }$ SIGNS"
    sys.exit(2)
  subprocess.call("rm script.py", shell=True)
 # print "##--------------------------------------------------------------------------------##"
  

# To name the lua file
# name is generated only with values without names. For tuple the value
# of first name is used
def namefile(name,p_name,x,num):
 for i in range(0,num):
   if isinstance(p_name[i],(tuple)):
#     for ii in range(len(p_name[i])):
#       #name = name+'_'+p_name[i][ii]+'_'+x[i][ii]
       name = name+'_'+x[i][0]
   else:
     #name=name+'_'+p_name[i]+'_'+str(x[i])
     name=name+'_'+str(x[i])
 return name


# Prints Info
def print_params(params, array, name):
  print "##--------------------------------------------------------------------------------##"
  if len(params)>0:
    print 'Loading Parameters in the '+name+' script... '
    print 'You have chosen to change %s parameters: %s'%(len(params),params)
    count=0
    for items in params:
      print 'The values read for parameter : %s are  %s'%(items,array[count])
      count=count+1
  print "##--------------------------------------------------------------------------------##"

# get paramters from python file
def get_param(params):
  array2 = []
  array1 = []
  array = []
  par = []
  #print len(params_m)
  num_params = len(params)
  for count in range(len(params)):
    if isinstance(params[count][0], (tuple)):
      par.append(params[count][0])
      
      len_tuple = len(params[count])
      for ii in range(len_tuple-1):
        array2.append([params[count][ii+1]])
      array.append(array2)
      array2=[]

    else:
      par.append(params[count][0])
      for ii in range(len(params[count])-1):
       #  print list(params[count][ii+1])
         array1.append([params[count][ii+1]])
      array.append(array1)
      array1 = []

  return array,par


##-------------------------------------------------------------------------------------------------------------##


##----------Define variables ----------------------------------------------------------------------------------##
p=[]
p_name=[]
array_m=[]
array_lua=[]
par_m = []
par_lua = []
lua_file=''
array = []
##-------------------------------------------------------------------------------------------------------------##


##----------Read Parameters------------------------------------------------------------------------------------##

#Read lua parameters from command file input file or default file params.py
if  (len(sys.argv) > 1):
  ifile = sys.argv[1]
else:
  ifile = 'params.py'

if not os.path.isfile(ifile):
  print 'Input file %s is not found in current dir', ifile
  sys.exit(1)

call(['cp',ifile, 'params_tmp.py'])

sys.path.insert(0, str(os.getcwd()))
from params_tmp import *
sys.path.insert(0, str(path_to_lib))
import pyratemp as pyratemplate

if run_exec == True:
  if submit_job == True:
     print 'Set True either for run_solver or submit job not for both. Or Both False'

if len(jobscript_template) != 0 :
  if not os.path.isfile(jobscript_template):
    print 'job script template file is not found in current dir'
    sys.exit(1)
  array_m,par_m = get_param(params=job_params) 
  print_params(params = par_m, array = array_m, name = 'lua')
  
if len(lua_template) != 0 :
  if not os.path.isfile(lua_template):
    print 'lua template file is not found in current dir'
    sys.exit(1)
  array_lua,par_lua = get_param(params = lua_params)    
  lua_fpath = lua_template.split('.')[0].split('/')
  lua_file=lua_fpath[len(lua_fpath)-1]
  print_params(params = par_lua, array = array_lua, name = 'lua')
elif lua_file != None :
  if not os.path.isfile(lua_file):
    print 'lua file is not found in current dir'
    sys.exit(1)
else:
  print 'specify either lua file or lua template'
  sys.exit(1)

for x in product(*array_lua):
    t=[]
    for items in x:
       t.append(items[0])
    # parameters to be changed
    if len(par_lua) > 0 :
        lua_fname=namefile(lua_file,par_lua,t,len(par_lua))
        genscript(lua_fname,lua_file,lua_template,par_lua,t,str(path_to_lib),'lua')
    # No parameter to be changed in lua file. take default musubi.lua
    else: 
       lua_fname = lua_file
       call(['cp',lua_template, lua_fname+'.lua'])

    # Running simulation (1. local 2.Generate jobscripts)
    if run_exec ==True:
      if len(path_to_exec)  == 0:
        print "specify 'path_to_exec' argument in input file"
      call(run_command+' '+lua_fname+'.lua', shell = True)

    #generate jobscripts
    for y in product(*array_m):
       u=[]
       for items in y:
          u.append(items[0])
       if len(par_m) > 0 :
         filename = namefile(lua_file,par_m,u,len(par_m))
         genscript(filename,lua_fname,jobscript_template,par_m,u,str(path_to_lib),'job')
    # Submitting the job
    if submit_job == True:
       filename = filename+'.job'
       call(sub_command+' '+filename)

 

call('rm params_tmp.py params_tmp.pyc', shell = True)


##-------------------------------------------------------------------------------------------------------------##
