#
# Copyright © 2020 MSC.Software Corporation
#  
# Permission to use Scripts
#  
# Permission is granted to MSC.Software customers with valid licenses of the MSC Apex™ software 
# to use script files posted on this page (collectively “Scripts”) solely for customers’ own authorized 
# internal use in conjunction with licensed use of the MSC Apex software.  
# No other use is permitted.  No license to MSC Apex or other software is granted under this Permission.
#  
# SCRIPTS ARE PROVIDED ON AN "AS-IS" BASIS, WITH NO WARRANTIES OF ANY KIND.  USE OF THE SCRIPTS IS AT CUSTOMER'S SOLE RISK.
#  
# IN NO EVENT SHALL MSC.SOFTWARE CORPORATION, ITS AFFILIATES, SUBSIDIARIES, SUPPLIERS, AGENTS, REPRESENTATIVES OR EMPLOYEES BE LIABLE FOR ANY 
# DIRECT, INDIRECT, INCIDENTAL, SPECIAL OR CONSEQUENTIAL DAMAGES HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, TORT, 
# STRICT LIABILITY, OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION USE OF THE SCRIPTS, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.  
#  
# Customer shall indemnify, defend and hold MSC.Software Corporation, its affiliates, subsidiaries, suppliers, agents, 
# employees or representatives (collectively, “Indemnified Parties”) harmless from and against any third-party claims 
# brought against Indemnified Parties rising out of or in connection with Customer’s use of the Scripts.
#
import os
import subprocess
import sys
from math import ceil

def read_card(card, double = False):
	list = []
	length = len(card)
	if not double:
		for i in range(length//8):
			list.append(card[8*i:8*(i+1)])
	else:
		for i in range(length//16):
			list.append(card[8*i:8*(i+1)])
	return list

def read_settings(settings_file, tmp_h=""):
	silent_flag = True
	#
	# settings_file=r'C:\Users\e7390\Documents\Predator\Topics\Scripting\Sample_files\UtilityUserSettings.xml'
	inf = open(settings_file, 'r')
	lines = inf.readlines()
	inf.close()
	keys = []
	SettingsD = {}
	n = 0
	while n < len(lines):
		if lines[n].find('<') > -1 and  lines[n].find('\\') < 0 and lines[n].find('/') < 0:
			# found start tag
			# print lines[n]
			tmp = lines[n].strip().replace('<', '').replace('>', '')
			# print tmp
			endtag = "<\\" + tmp + ">"
			endtag2 = "</" + tmp + ">"
			# print endtag
			n += 1
			SettingsD[tmp] = {}
			while lines[n].find(endtag) < 0 and lines[n].find(endtag2) <0 :
				#while lines[n].find(endtag) < 0 :
				if lines[n].find('=') > 1:
					newkey = lines[n].strip().split('=')[0]
					SettingsD[tmp][newkey] = lines[n].strip().split('=')[1]
					n += 1
				elif lines[n].find('#') == 0:
					continue
				else:
					# not a valid settnigs command
					#print "Not a valid settngs command: " + lines[n]
					n += 1
				#print(lines[n])
		n += 1

	# supress write out of all settings

	if silent_flag != True:
		if tmp_h != -1:
			print("====")
			print("Following setting groups detected:")

		for item in reversed(sorted(SettingsD.keys())):
			if tmp_h != -1:
				print("==== " + item + "   " + " ====")

			for key in list(SettingsD[item].keys()):
				if tmp_h != "" and tmp_h != -1:
					print("%-16s : %-12s" % (key, SettingsD[item][key].strip()))
				elif tmp_h == -1:
					continue
				else:
					print("%-16s : %-12s" % (key, SettingsD[item][key].strip()))
	#
	return SettingsD

def write_RANDOM_bdf_stuff(bdf_file, SettingsD, OptionsD={}):

	# Split BCONECT cards in case the new format is used
	BConprg_initial_D={}
	BConect_relations_D={}
	bdf_h = open(bdf_file, 'r')
	bdf_lines = bdf_h.readlines()
	bdf_h.close()
	#delete_bdf
	bdf_ = open(bdf_file, 'w+')
	delete = []
	skip = False
	dynamic = True
	for line in bdf_lines:

		if line[0] == "$":
			if line.upper().find("FREQUENCY RESPONSE"):
				line = line.upper().replace("FREQUENCY RESPONSE", "RANDOM RESPONSE")
			bdf_.write(line)
			#continue
		elif line.find("CEND") > -1:
			bdf_.write(line)
			bdf_.write("$\n")
			bdf_.write("$\n")
			random_SID = 10000
			bdf_.write("RANDOM = "+str(random_SID)+"\n")
			bdf_.write("$\n")
			bdf_.write("$\n")
		elif line.find("SUBCASE") > -1:
			bdf_.write(line)
			subcase_line = line.split()
			subcase = int(subcase_line[1])
		elif line.find("BEGIN BULK") > -1:
			bdf_.write(line)
			bdf_.write("$\n")
			bdf_.write("$\n")
			bdf_.write("PARAM,RMSINT,LOGLOG\n")
			bdf_.write("$\n")
			bdf_.write("$\n")
		elif line.find("MDLPRM  OFFDEF  LROFF") > -1:
			bdf_.write("$\n")
			bdf_.write("$\n")
			bdf_.write("$ PSD INPUT\n")
			# bdf_.write("$------$$------$$------$$------$$------$$------$$------$$------$$------$$------$\n")
			TID = 10001
			bdf_.write("%-8s%-8d%-8d%-8d%-8.1f%-8.1f%-8d\n" % ('RANDPS',random_SID,subcase,subcase, 1.0, 0.0, TID))
			bdf_.write("$\n")
			bdf_.write("$\n")
			# bdf_.write("$------$$------$$------$$------$$------$$------$$------$$------$$------$$------$\n")
			# bdf_.write("$------$$--------------$$--------------$$--------------$$--------------$$------$\n")
			bdf_.write("%-8s%-16d%-16s%-16s%-16s%-8s\n" % ("TABRND1*",TID, "LOG", "LOG", "","*"))
			bdf_.write("%-8s%-16s%-16s%-16s%-16s%-8s\n" % ("*","", "", "", "","*"))

			if len(SettingsD["NASTRAN_JOB_SETUP"]["RANDOMPSD_Frec"]) % 2 == 0:
				for i in range(0,int(len(SettingsD["NASTRAN_JOB_SETUP"]["RANDOMPSD_Frec"])/2)):
					if i != len(SettingsD["NASTRAN_JOB_SETUP"]["RANDOMPSD_Frec"])/2-1:
						bdf_.write("%-8s%-16.2f%-16.2f%-16.2f%-16.2f%-8s\n" % ('*', float(SettingsD["NASTRAN_JOB_SETUP"]["RANDOMPSD_Frec"][2*i]), float(SettingsD["NASTRAN_JOB_SETUP"]["RANDOMPSD_Mag"][2*i]), float(SettingsD["NASTRAN_JOB_SETUP"]["RANDOMPSD_Frec"][2*i+1]), float(SettingsD["NASTRAN_JOB_SETUP"]["RANDOMPSD_Mag"][2*i+1]), '*'))
					else:

						bdf_.write("%-8s%-16.2f%-16.2f%-16.2f%-16.2f%-8s\n" % ('*', float(SettingsD["NASTRAN_JOB_SETUP"]["RANDOMPSD_Frec"][2*i]), float(SettingsD["NASTRAN_JOB_SETUP"]["RANDOMPSD_Mag"][2*i]), float(SettingsD["NASTRAN_JOB_SETUP"]["RANDOMPSD_Frec"][2*i+1]), float(SettingsD["NASTRAN_JOB_SETUP"]["RANDOMPSD_Mag"][2*i+1]), '*'))
						bdf_.write("%-8s%-8s\n" % ('*', 'ENDT'))
			else:
				for i in range(0,ceil(len(SettingsD["NASTRAN_JOB_SETUP"]["RANDOMPSD_Frec"])/2)):
					if i != ceil(len(SettingsD["NASTRAN_JOB_SETUP"]["RANDOMPSD_Frec"])/2-1):
						bdf_.write("%-8s%-16.2f%-16.2f%-16.2f%-16.2f%-8s\n" % ('*', float(SettingsD["NASTRAN_JOB_SETUP"]["RANDOMPSD_Frec"][2*i]), float(SettingsD["NASTRAN_JOB_SETUP"]["RANDOMPSD_Mag"][2*i]), float(SettingsD["NASTRAN_JOB_SETUP"]["RANDOMPSD_Frec"][2*i+1]), float(SettingsD["NASTRAN_JOB_SETUP"]["RANDOMPSD_Mag"][2*i+1]), '*'))
					else:
						bdf_.write("%-8s%-16.2f%-16.2f%-8s\n" % ('*', float(SettingsD["NASTRAN_JOB_SETUP"]["RANDOMPSD_Frec"][2*i]), float(SettingsD["NASTRAN_JOB_SETUP"]["RANDOMPSD_Mag"][2*i]),  'ENDT'))

			bdf_.write(line)
		else:
			bdf_.write(line)

	bdf_.close()
	if not dynamic:
		os.remove(bdf_.name)
		print("The Scenario selected is not Dynamic... Export canceled.")
		sys.exit()

	return

def run_nastran(bdf_file, SettingsD="", xtra_args=[]):


	go_flag = False
	try:
		print("Look for nastran executable in UtilityUserSettings.xml")
		nas_exe = SettingsD['System']['NastranPath']
		if not os.path.isfile(nas_exe):
			print("Path in UtilityUserSettings.xml is invalid")
		else:
			go_flag = True
	except:
		print("Could not locate nastran path setting in UtilityUserSettings.xml")



	if not go_flag:
		print("")
		# get Nastran path through settings file
		try:
			nas_exe = SettingsD['System']['NastranPath']
			if os.path.isfile(nas_exe):
				print(("Located nastran executable through settings file: " + nas_exe ))
				go_flag = True

		except:
			print("Failed to find a Nastran executable through Settings file")
			go_flag = False



		if not go_flag:
			print("Locating nastran exceutable  using registry path")
			#nas_exe=C:\MSC.Software\MSC_Nastran\20180\bin\nastranw.exe
			try:
				nas_exe=getPath(r'HKEY_CLASSES_ROOT\Applications\nastranw.exe\shell\open\command').replace('nastranw.exe','nastran.exe')
				if os.path.isfile(nas_exe):
					print(("Located nastran executable through registry: " + nas_exe ))
					go_flag = True


			except:
				print("Failed to obtain nastran through Registry")
				go_flag = False


	if go_flag:
		args = []
		args.append(nas_exe)
		args.append(bdf_file)
		# args.append("dbs=%s" % (os.path.dirname(bdf_file)))
		args.append("out=%s" % (os.path.dirname(bdf_file)))
		args.append("scr=yes")
		# add xtra_args
		for arg in xtra_args:
			args.append(arg)

		print("Nastran executable args:")
		print(args)
		# specify current working directory for the execution of nastran
		nastran_cwd = os.path.dirname(bdf_file)

		# modify the SCA resource dir env variable, that conflicts the nastran run
		my_env = os.environ
		my_env["SCA_RESOURCE_DIR"] = ""
		# SCA_RESOURCE_DIR=c:\msc.software\msc_nastran\20141\msc20141\res

		# p = subprocess.Popen(args,shell=True, stdout=subprocess.PIPE,stderr=subprocess.PIPE,stdin=subprocess.PIPE,cwd=nastran_cwd)
		p = subprocess.Popen(args, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE, stdin=subprocess.PIPE,
							 cwd=nastran_cwd, env=my_env)
		out, err = p.communicate()
		p.stderr.close()
		p.stdin.close()
	# print out
	# print "out: " + out
	# print "err: " + err

	else:
		out = "*** nastran execution failed"
	return out


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

# if __name__ == "__main__":
#
# 	settings_file =r"C:\Users\e11352\Documents\GitHub\APEX-Utilities-Test\Utilities\Export\Export112\res\UtilityUserSettings.xml"
# 	bdf_full_name=r"C:\Users\e11352\Documents\GitHub\APEX-Utilities-Test\Utilities\Export\Export112\res\DynamicScenario_preLoad.bdf"
# 	SettingsD=read_settings(settings_file)
