# TCP server example
import socket
import aview_main
import string
import os

tempFileName = "the_response.txt"

class CommandListener:

	def __init__(self,port):
		self.someError = 0
		self.server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
		self.p = port
		try:
			self.server_socket.bind(("", self.p))
			self.server_socket.listen(5)
			mycmd = "var set var=Isight_stop_condition integer=0"
			aview_main.execute_cmd(mycmd)

			print "TCPServer Waiting for client on port " + str(self.p)
			readyFile = open("serverReady.txt","w")
			readyFile.write("Server Ready")
			readyFile.close()

			# It will get hung at this point:
			self.client_socket, self.address = self.server_socket.accept()
		except:		
			self.someError = 1
			readyFile = open("serverReady.txt","w")
			readyFile.write("Could not connect to server, port is: " + str(self.p))
			readyFile.close()
			
			
		# Will this command run?:
## 		mycmd = "var set variable=bongowongo real_value = 19"
## 		aview_main.execute_cmd(mycmd)
## 		data = client_socket.recv(512)

	def SimpleCommand(self):
		mycmd = "var set variable=bongowongo real_value = 13"
		aview_main.execute_cmd(mycmd)

	def ViewElementExists(self, ElementName):
		# Check for existence of element with given name...
		sTest = "DB_EXISTS('%s')" % ElementName
		return aview_main.evaluate_exp(sTest)
	
	def CleanUp(self):
		# Just destroy sockets..
		self.client_socket.close()
		self.server_socket.close()

	def FilterInput(self, theCommands):
		# Implement the simple rules for acceptable input requests:
		goodCommands = 0
		if len(theCommands) > 0:
			theVerb = theCommands[0]
			if theVerb in ("simulate", "variable", "objective", "quit", "quit_server"):
				if theVerb == "simulate":
					goodCommands = (len(theCommands) == 2)
				if theVerb == "variable":
					goodCommands = (len(theCommands) == 3)
				if theVerb == "objective":
					goodCommands = (len(theCommands) == 2)
				if theVerb == "quit":
					goodCommands = 1
				if theVerb == "quit_server":
					goodCommands = 1
		return goodCommands
	
			
	def EvaluateObjective(self, ObjectiveName):
		# All this just to find the objective...:
		# Make sure temp file does not exist on disk:
		if os.path.exists(tempFileName):
			os.remove(tempFileName)
			
		# Clear info window:
		aview_main.execute_cmd("info_window empty")
				
		# Evaluate objective:
		aview_main.execute_cmd("optimize objective evaluate objective_name = %s" % ObjectiveName) 
		# Write contents to file:
		aview_main.execute_cmd("interface field write field_name = .gui.info_window.info_text file_name = '%s'" % tempFileName)

		# Read file, parse values to get objective:
		file = open (tempFileName)
		alltext = file.read()
		allwords = string.split(alltext)
		wordcount = 0
		valueindex = 0
		for word in allwords:
			wordcount = wordcount + 1
			if (word == "="):
				# found the equals sign. The actual value follows this, but things are zero-indexed:
				valueindex = wordcount 
				break
		
		if (valueindex > 0):
			response_value = allwords[valueindex]
		else:
			response_value = -9999999

		file.close()
		
		# return objective:
		return response_value

	def EvaluateObjective_BatchMode(self, ObjectiveName):

		aviewLog = "aview.log"

		# First make sure that the Objective gets written to the aview.log file:
		mycmd = "optimize objective evaluate objective_name = %s" % ObjectiveName
		aview_main.execute_cmd(mycmd)
		
		if not os.path.exists(aviewLog):
			response_value = -9999999
			return response_value

		theLog = open(aviewLog)
		allLines = theLog.readlines()
		totalLines = len(allLines)
		if totalLines > 0:
			# Everything is ok
			ObjectiveLine = allLines[totalLines - 1]
			allWords = string.split(ObjectiveLine)
			wordcount = 0
			valueindex = 0
			for word in allWords:
				wordcount = wordcount + 1
				if (word == "="):
					# found the equals sign. The actual value follows this, but things are zero-indexed:
					valueindex = wordcount 
					break

			if (valueindex > 0):
				response_value = allWords[valueindex]
			else:
				response_value = -9999999

		else:
			# no lines in log file? Abort:
			response_value = -9999999
			

		return response_value
	

		
	def ListenForValue(self):
	
		if(self.someError == 1):
			mycmd = "variab set variab = Isight_stop_condition inte=1"
			aview_main.execute_cmd(mycmd)
		
		data = self.client_socket.recv(512)
		if (len(data) == 0):
			self.client_socket.send("ERROR: Could not understand input command!")
			return
		
		data_array = string.split(data)
		if ((len(data_array) > 0) & (self.FilterInput(data_array))):
			if (data_array[0] == 'simulate'):
				if self.ViewElementExists(data_array[1]):
					mycmd = "simulation single_run scripted sim_script_name = %s reset_before_and_after = yes" % data_array[1]

					aview_main.execute_cmd(mycmd)
					self.client_socket.send("OK")
				else:
					self.client_socket.send("Error: Simulation Script does not exist")

			elif (data_array[0] == 'variable'):
				if self.ViewElementExists(data_array[1]):
					mycmd = "variab set variab = %s real = %s" % (data_array[1], data_array[2])
					aview_main.execute_cmd(mycmd)
					self.client_socket.send("OK")
				else:
					self.client_socket.send("Error: Variable does not exist")
					
			elif (data_array[0] == 'objective'):
				# 
				if self.ViewElementExists(data_array[1]):
					# Just evaluate the objective:
					retValue = self.EvaluateObjective_BatchMode(data_array[1])
					
					self.client_socket.send("Objective value is: %s" % retValue)
				else:
					self.client_socket.send("Error: Objective does not exist")

			elif (data_array[0] == "quit"):
				#mycmd = "variab set variab = Isight_stop_condition inte=1"
				#aview_main.execute_cmd(mycmd)
				#self.client_socket.send("QUIT")
				self.client_socket.close()
				
				# It will get hung at this point:
				self.client_socket, self.address = self.server_socket.accept()
			
			elif (data_array[0] == "quit_server"):
				mycmd = "variab set variab = Isight_stop_condition inte=1"
				aview_main.execute_cmd(mycmd)
			
		else:
			# Got some input, but it wasn't meaningful:
			self.client_socket.send("ERROR: Could not understand input command!")
