#!/usr/bin/python
import sys, os
from shlex import shlex
from threading import Thread

debug = False

class Parser(Thread):
	variables = {}

	def __init__(self, filename, display_callback):
		Thread.__init__(self)
		file = open(filename, 'r')
		started = False
		self.display_callback = display_callback
		self.install = []
		for line in file.readlines():
			if line[:21] == "####START INSTALL####":
				started = True
			if line[:19] == "####END INSTALL####":
				break
			if not started:
				continue
			self.install.append(line)
			
		installstr = ""
		for line in self.install:
			installstr += line
			
		self.lex = shlex(installstr, None, True)     #POSIX compliant mode
		self.lex.quotes = self.lex.quotes + "`"
		self.lex.wordchars = self.lex.wordchars + '&' + '-' + '!' + '='
		self.running = False
		
	def run(self):	
		self.running = True
		self.process(self.lex)

	def stop(self):
		self.running = False
		self.display_callback("Stopping...")
	
	def parsevars(self, string):
		for key, value in self.variables.items():
			string = string.replace(key, value)
		return string

	#TODO: Clean this mess up.
	def process(self, lex, state = None):
		conditional = False
		var1 = None
		var2 = None

		while 1:
			if not self.running:
				break

			token = lex.get_token()
			original = self.install[lex.lineno - 2]
			original = original.replace("\n", "")
			original = original.replace("\t", "")

			if not token:
				break

			if token == "fi":
				return
			elif state == "then" and conditional == False:
				if token == "if":
					self.process(lex, "then") #Process, but do nothing due to 'then'
				continue
			elif token == "if":
				self.process(lex, "if")
			elif token == "then":
				state = "then"
		
			elif token == "echo":
				labelstr = lex.get_token()
				labelstr = self.parsevars(labelstr)
				self.display_callback(labelstr)
			elif len(original) > 0 and original[0] == "`" and original[-1] == "`":
				token = self.parsevars(token)
				os.popen(token)
			elif state == "if" and token == "-n":
				state = "exists"
			elif state == "exists":
				conditional = self.variables.has_key(token)
				state = None
			elif state == "if" and token[:1] == "$":
				var1 = token
			elif state == "if" and token == "!=":
				state = "notequal"
			elif state == "notequal" and var2 == None:
				var2 = token
			elif state == "notequal" and var1 and var2:
				if var1[:1] == "$" and not self.variables.has_key(var1):
					if debug: print var1, "not defined"
					continue
				if var2[:1] == "$" and not self.variables.has_key(var2):
					if debug: print var2, "not defined"
					continue
				if var1[:1] == "$": var1 = self.variables[var1]
				if var2[:1] == "$": var2 = self.variables[var2]
				if var1 == "None": var1 = None
				if var2 == "None": var2 = None
				if var1 != var2:
					conditional = True
			else:
				if debug:
					print "[UNKNOWN]" + token


