#!/usr/bin/env python

import os, sys, time, cPickle, traceback, cStringIO, re
from db_vars import *

from toolfunc import *


error_msg = []
R_halt_str = re.compile(r'\nExecution halted\n*\Z')
error_head = '<h1>Error Message</h1><br><p>'

R_CMD = 'R'
R_code_dir = os.path.join(os.path.split(os.path.realpath(__file__))[0], 'R_code')

def htmlStr(s): return s.replace('\n','<br>').replace('"', "''")

def runR_pipe():
	#req_type, req_id, user_params, R_code_dir = cPickle.loads( sys.stdin.read() )
	req_type, req_id, user_params = cPickle.loads( sys.stdin.read() )
	user_list = "user.params <- " + GetStr(user_params) + ';\n'

	rlt = None
	error_msg = []
	try: 
		lcwd = os.getcwd()
		os.chdir(R_code_dir)
		#Rin, Rout = os.popen4('R --vanilla')
		RCMD = R_CMD
		if os.path.exists(RCMD): # then RCMD might be a link under R_code_dir. It have to be a realpath if the daemon run from /etc/rc.d/rc.local
			RCMD = os.path.realpath(RCMD)
		Rin, Rout = os.popen4('%s --vanilla' % RCMD)
		#Rin, Rout = os.popen4('/home/xxia/other/bin/R-2.4.0/bin/R --vanilla')
		#Rin.write(user_list)
		os.write(Rin.fileno(), user_list)
		if req_type in (TYPE_NORM_ANALYSIS, TYPE_LINEAR_DUAL):
			#Rin.write("source('LinearDual.R')")
			os.write(Rin.fileno(), "source('LinearDual.R');\n")
		elif req_type == TYPE_LINEAR_AFFY:
			#Rin.write("source('LinearAffy.R')")
			os.write(Rin.fileno(), "source('LinearAffy.R');\n")
		elif req_type == TYPE_NORMPCA:
			os.write(Rin.fileno(), "source('InitParams.R');\n")
			os.write(Rin.fileno(), "source('normPCA.R');\n")
			os.write(Rin.fileno(), "fullNormalize(intensity_file, output_dir, chart_dir, plotPCA=plotPCA, plotAF=plotAF, plotAFD=plotAFD, plotHK=plotHK, sig_level=sig_level, ave_num=ave_num);\n") 
		else:
			rlt = None # do other analysis
		Rin.close()
		rlt = Rout.read()
		Rout.close()
		os.chdir(lcwd)
	except: 
		os.chdir(lcwd)
		rlt = None
		error_msg.append(error_head + 'Error happened in R: <p>') #might caused by wrong parameters from user.')
		cfile = cStringIO.StringIO()
		traceback.print_exc(None,cfile)
		value = htmlStr(cfile.getvalue())

		err_tk = 'error: '
		err_st = value.find(err_tk)
		if err_st >= 0: value = value[err_st+len(err_tk):]
		error_msg.append(value)
			
	# try...except seems not be able to detect error in R even if R halts. Then codes needed here
	if rlt and R_halt_str.search(rlt): error_msg.append(error_head + htmlStr(rlt))
			
	if error_msg:
		error_msg.append('''<p><spacer type='vertical' size=250>
<table><tr><td height=120></td></table>
<hr width=50% align=center>
<center>
<font size=-1>
	Please report bugs to <a href=mailto:xxia@skcc.org>Xiao-Qin Xia</a><br>For questions about analysis, please contact <a href=mailto:ywang@skcc.org>Yipeng Wang</a><br><a href=http://www.skcc.org>Sidney Kimmel Cancer Center</a></font>
</center>
''')
		msg = ' '.join(error_msg)
		req_state = STATE_ERROR
		sql_update = 'UPDATE requests SET req_state=%d, error_msg="%s" WHERE req_id=%d' % (req_state, msg, req_id)
	else: 
		req_state = STATE_SOLVED
		date_time = time.strftime('%Y-%m-%d %H:%M:%S', time.gmtime())
		sql_update = 'UPDATE requests SET req_state=%d, solve_time="%s" WHERE req_id=%d' % (req_state, date_time, req_id)
	sys.stdout.write( cPickle.dumps( (rlt, sql_update) ) )
	sys.stdout.close()


if __name__ == '__main__':
	try:	
		runR_pipe()
	except:
		cfile = cStringIO.StringIO()
		traceback.print_exc(None,cfile)
		value = htmlStr(cfile.getvalue())
		os.write(sys.stdout.fileno(), cPickle.dumps( ('Nothing done', value) ) )
	
