#!/usr/bin/env python
# -*- coding: utf-8 -*-
# PYTHON_ARGCOMPLETE_OK
import os
import requests
import sys
from subprocess import call
import time
import re
from requests.packages.urllib3.exceptions import InsecureRequestWarning

import argcomplete, argparse
parser = argparse.ArgumentParser()
parser.add_argument("command", choices=['monitore','run','m','r', 'debug', 'd', 'compile', 'c'], default='run')
parser.add_argument("file",  default=os.getcwd(), nargs='?')
parser.add_argument("class_module",choices=['eb302a','mc102abcd','mc102ef','mc102gh','mc102ij','mc102klmn','mc102op',
	'mc102qr','mc102st','mc102uvxz','mc102wy','mc202bc','mc202d','mc346a','mc404abe','mc404c','mc458ab','mc613ab',
	'mc658ab','mc833ab','mc999','mo644a','si100a','si100b','tt314a'], default='mc102wy', nargs='?')
argcomplete.autocomplete(parser)
args = parser.parse_args()

if len(sys.argv) < 2:
	sys.exit("Invalid number of parameters")

monitore = False;
debug = False;

if args.command == "m" or args.command == "monitore":
	monitore = True
elif args.command == "d" or args.command == "debug":
	debug = True

if len(sys.argv) < 3:
	sys.exit("Invalid number of parameters")

if not os.path.isfile(args.file):
	sys.exit("File '" + args.file + "' not found.")

file_name = args.file[:-2]
class_module = args.class_module

requests.packages.urllib3.disable_warnings(InsecureRequestWarning)

lab_names_raw = requests.get('https://susy.ic.unicamp.br:9999/' + class_module + '/', verify=False).text

lab_names_lines = re.split('(<[^>]*>)', lab_names_raw)
lab_names = []
lab_names_lines = [x for x in lab_names_lines if x]
for i in range(0,len(lab_names_lines)):
	if lab_names_lines[i] == '</TABLE>':
		break
	if lab_names_lines[i] == '<TR>':
		lab_names.append(lab_names_lines[i+3])


print "Received file is: ", file_name
while True : 
	if os.path.isfile(file_name):
		os.remove(file_name)

	print "Compiling " + file_name + ".c to " + file_name 
	os.system("gcc -Wall -std=c99 -pedantic *.c -o " + file_name + " -lm")
	
	if args.command == "compile" or args.command == "c":
		break;

	if not os.path.isfile(file_name): 
		sys.exit('\033[91m' + " Error during compilation" + '\033[0m');

	lab_number = ""
	for lab_name in lab_names:
		if lab_name.upper() == file_name.upper():
			lab_number = lab_name
			break


	inputs = []
	expected_outputs = []
	outputs = [];
	outputs.append("");

	print '\033[93mLOADING TESTS\033[0m'
	for i in range(1,7):
		inputs.append(requests.get('https://susy.ic.unicamp.br:9999/' + class_module + '/' + lab_number + '/dados/arq0'+str(i)+'.in', verify=False).text)
		expected_outputs.append(requests.get('https://susy.ic.unicamp.br:9999/' + class_module + '/' + lab_number + '/dados/arq0'+str(i)+'.res', verify=False).text)


	out_file = open('outfile', 'w+')
	out_file.close()

	failed = 0

	for i in range(0,6):
		print  '\033[93m' + "------------------------------------------" + '\033[0m'
		print '\033[93m' + "-------------STARTING ("+str(i+1)+"/6)---------------" + '\033[0m'
		in_file = open('infile', 'w+')
		in_file.write(inputs[i].encode('utf-8'))
		in_file.close()
		os.system("./"+file_name + " < infile" + " > outfile")

		out_file = open('outfile', 'r')
		output_resulted = out_file.read()
		output_lines = output_resulted.splitlines()

		debug_output = ""
		real_output = ""
		for line in output_lines:
			if line[0 : 4] == "[DB]":
				debug_output += line[4:] + '\n'
			else:
				real_output += line  + '\n'

		out_file.close()

		if real_output.decode("utf-8") == expected_outputs[i]:
			print "TEST "+str(i+1)+ '\033[92m' + " SUCCESS" + '\033[0m'
		else:
			failed += 1
			print "TEST "+str(i+1) + '\033[91m' + " FAILED" + '\033[0m'
			if not debug:
				print "EXPECTED\n" + expected_outputs[i]
				print "FOUND\n" + real_output

		if debug_output != "":
			print '\033[93m' + "DEBUG MESSAGES:" + '\033[0m\n' + debug_output

	print '\033[93m' + "------------------------------------------" + '\033[0m'
	print "Tests finished running with success"
	if failed == 0:
		print "All tests passed!. :D"
	else:
		print str(failed), "tests out of 6 have failed. :-("

	os.remove('infile')
	os.remove('outfile')
	os.remove(file_name)

	if not monitore:
		break
	else:
		mod_date_first = os.stat(file_name + ".c")[8]
		mod_date_new = os.stat(file_name + ".c")[8]
		while mod_date_new == mod_date_first:
			mod_date_new = os.stat(file_name + ".c")[8]
			time.sleep(1)