'''
Accessible Access Control 1.0
2012-2104 Michigan Technological University
Supported in part by NSF grants: DUE-1140512, DUE-1245310 and IIS-1319363
Developer: Yifei Li
Advisors:Dr. Steve Carr, Dr. Jean Mayo, Dr. Ching-Kuang Shene and Dr. Chaoli Wang
'''
"""
             ThreadMentor: Thread Visualization System
           (c)2012-2014 Michigan Technological University

@author: Man Wang
@date: Oct. 21, 2013
"""''''
created on Sep 17, 2012

@author: manw
'''
from PyQt4.QtGui import QMainWindow, QWidget, QFileDialog, QMessageBox, QGraphicsItem, QListView
from PyQt4.QtCore import pyqtSignal, Qt
from Ui_QueryWindow import Ui_Form
from QueryOutput import QueryOutput
from DomainNode import DomainNode
from TypeNode import TypeNode
from FileNode import FileNode
from EdgeItem import EdgeItem
from QueryWindow import QueryWindow
from DiagramScene import DiagramScene
from DiagramIOHelper import DiagramIOHelper
import string
import re
import os

class Autograde():
    def __init__(self, inputSpec, answerfile, outputGradefile):
        self.inputSpec = inputSpec
        self.answerfile = answerfile
        self.outputGradefile = outputGradefile
        self.scene = DiagramScene()
        self.queryWindow = QueryWindow(self.scene)
        self.ioHelper = DiagramIOHelper(self.scene)
        self.animationEnabled = False
        self.queryInputs = {}
        self.answers = []
        self.answerToEach = ''
        self.stuAnswerToEach = ''
        self.stuAnswers = ''
        self.grademode = ''
        self.score = 0
        self.strquery0 = ' 0. Type of a file'
        self.strquery1 = ' 1. The files which can be accessed by a binary'
        self.strquery2 = ' 2. The files which can be accessed by a binary in certain mode'
        self.strquery3 = ' 3. The files which can be accessed from a domain in certain mode'
        self.strquery4 = ' 4. If a binary can access a file in a certain mode'
        self.strquery5 = ' 5. Domains from which a binary can be executed'
        self.strquery6 = ' 6. Domains from which a file can be accessed in a certain access mode'
        self.strquery7 = ' 7. Are there files with no assigned type' 
        self.strquery8 = ' 8. Are there files that cannot be accessed with a certain access mode'
        self.strquery9 = ' 9. Resulting type of a file created from a domain'
        self.strquery10 = '10. Result of executing a binary from a domain'
        self.autograde(self.inputSpec, self.answerfile, self.outputGradefile)    
        return

    def manualQuerylist(self):
        print 'Please select the query questions for grading:'
        strTmp =  self.strquery0+'\n'+self.strquery1+'\n'+self.strquery2+'\n'+self.strquery3+'\n'+self.strquery4+'\n'+self.strquery5+'\n'+self.strquery6+'\n'+self.strquery7+'\n'+self.strquery8+'\n'+self.strquery9+'\n'+self.strquery10
        print strTmp

    def readAnswerFileManual(self, answerfile):

        answerFile = open(answerfile, "r")
        self.answers = answerFile.read()
        self.answerToEach = string.split(self.answers, "\n")
        answerFile.close()

    def readAnswerFileAuto(self, answerfile):
        strTmp = ''
        answerFile = open(answerfile, "r")
        self.answers = answerFile.read()
        answerEachline = string.split(self.answers, "\n")
        querylist = answerEachline[0]
        queryIndex = string.split(querylist, ' ')
        for i in range(len(queryIndex)):
            self.queryInputs[queryIndex[i]] = answerEachline[i+1]
        for i in range(len(queryIndex)+1,len(answerEachline)):
            strTmp += answerEachline[i]+'\n'
        self.answerToEach = string.split(strTmp, '\n')
        answerFile.close()
        return querylist 

    def stuSpecQuery(self, querylist): 
        stuAnswerFile = open("./Grading/stuAnswerFile.txt","w+")
        query = string.split(querylist, ' ')
        separator = '\n     '
        for item in query:
            if item == '0':
                print '[Query0] Please input file name:'
                if self.grademode == '1' and self.queryInputs[item] != None:
                    filename = self.queryInputs[item]
                else:
                    filename = raw_input()
                type = self.queryWindow.runQuery0(filename)
                strTmp = self.strquery0+separator+filename+separator+type.name
                stuAnswerFile.writelines(strTmp+'\n')
                self.stuAnswers += type.name+'\n'
                print strTmp
            if item == '1':
                print '[Query1] Please input binary name:'
                if self.grademode == '1' and self.queryInputs[item] != None:
                    binaryname = self.queryInputs[item]
                else:
                    binaryname = raw_input()
                files = self.queryWindow.runQuery1(binaryname)
                strTmp = self.strquery1+separator+binaryname+separator+files
                stuAnswerFile.writelines(strTmp+'\n')
                self.stuAnswers += files+'\n'
                print strTmp
            if item == '2':
                print '[Query2] Please input binary name and access mode:'
                if self.grademode == '1' and self.queryInputs[item] != None:
                    temp = string.split(self.queryInputs[item],' ')
                    binaryname = temp[0]
                    mode = temp[1]
                else:
                    binaryname = raw_input()
                    mode = raw_input()
                files = self.queryWindow.runQuery2(binaryname, mode)
                strTmp = self.strquery2+separator+binaryname+' '+mode+separator+files
                stuAnswerFile.writelines(strTmp+'\n')
                self.stuAnswers += files+'\n'
                print strTmp
            if item == '3':
                print '[Query3] Please input domain name and access mode:'
                if self.grademode == '1' and self.queryInputs[item] != None:
                    temp = string.split(self.queryInputs[item],' ')
                    domainname = temp[0]
                    mode = temp[1]
                else:
                    domainname = raw_input()
                    mode = raw_input()
                files = self.queryWindow.runQuery3(domainname, mode)
                strTmp = self.strquery3+separator+domainname+' '+mode+separator+files
                stuAnswerFile.writelines(strTmp+'\n')
                self.stuAnswers += files+'\n'
                print strTmp
            if item == '4':
                print '[Query4] Please input binary name, file name and access mode'
                if self.grademode == '1' and self.queryInputs[item] != None:
                    temp = string.split(self.queryInputs[item],' ')
                    binaryname = temp[0]
                    filename = temp[1]
                    mode = temp[2]
                else:
                    binaryname = raw_input()
                    filename = raw_input()
                    mode = raw_input()
                flag = self.queryWindow.runQuery4(binaryname, filename, mode)
                strTmp = self.strquery4+separator+binaryname+' '+filename+' '+mode+separator+flag
                stuAnswerFile.writelines(strTmp+'\n')
                self.stuAnswers += flag+'\n'
                print strTmp
            if item == '5':
                print '[Query5] Please input binary name:'
                if self.grademode == '1' and self.queryInputs[item] != None:
                    binaryname = self.queryInputs[item]
                else:
                    binaryname = raw_input()
                domains = self.queryWindow.runQuery5(binaryname)
                strTmp = self.strquery5+separator+binaryname+separator+domains
                stuAnswerFile.writelines(strTmp+'\n')
                self.stuAnswers += domains+'\n'
                print strTmp
            if item == '6':
                print '[Query6] Please input file name and access mode'
                if self.grademode == '1' and self.queryInputs[item] != None:
                    temp = string.split(self.queryInputs[item],' ')
                    filename = temp[0]
                    mode = temp[1]
                else:
                    filename = raw_input()
                    mode = raw_input()
                domains = self.queryWindow.runQuery6(filename, mode)
                strTmp = self.strquery6+separator+filename+' '+mode+separator+domains
                stuAnswerFile.writelines(strTmp+'\n')
                self.stuAnswers += domains+'\n'
                print strTmp
            if item == '7':
                print '[Query7]'
                msg = self.queryWindow.runQuery7()
                strTmp = self.strquery7+separator+msg
                stuAnswerFile.writelines(strTmp+'\n')
                self.stuAnswers += msg+'\n'
                print strTmp
            if item == '8':
                print '[Query8] Please input access mode'
                if self.grademode == '1' and self.queryInputs[item] != None:
                    mode = self.queryInputs[item]
                else:
                    mode = raw_input()
                msg = self.queryWindow.runQuery8(mode)
                strTmp = self.strquery8+separator+mode+separator+msg
                stuAnswerFile.writelines(strTmp+'\n')
                self.stuAnswers += msg+'\n'
                print strTmp
            if item == '9':
                print '[Query9] Please input domain name and file name:'
                if self.grademode == '1' and self.queryInputs[item] != None:
                    temp = string.split(self.queryInputs[item],' ')
                    domainname = temp[0]
                    filename = temp[1]
                else:
                    domainname = raw_input()
                    filename = raw_input()
                result = self.queryWindow.runQuery9(domainname, filename)
                strTmp = self.strquery9+separator+domainname+' '+filename+separator+result
                stuAnswerFile.writelines(strTmp+'\n')
                self.stuAnswers += result+'\n'
                print strTmp
            if item == '10':
                print '[Query10] Please input domain name and file name:'
                if self.grademode == '1' and self.queryInputs[item] != None:
                    temp = string.split(self.queryInputs[item],' ')
                    domainname = temp[0]
                    filename = temp[1]
                else:
                    domainname = raw_input()
                    filename = raw_input()
                result = self.queryWindow.runQuery10(domainname, filename)
                strTmp = self.strquery10+separator+domainname+' '+filename+separator+result
                stuAnswerFile.writelines(strTmp+'\n')
                self.stuAnswers += result+'\n'
                print strTmp
        self.stuAnswerToEach = string.split(self.stuAnswers, '\n')
        print 'The student\'s answer has been written to ./Grading/stuAnswer.txt'  
        stuAnswerFile.close()
        
    def writeToGradeFile(self, gradefile):
        gradefile = open("./Grading/grade.txt", "w+")
        for i in range(len(self.stuAnswerToEach)-1):
            if self.answerToEach[i] == self.stuAnswerToEach[i]:
                gradefile.write("Right\n")
                self.score+=1
            else:
                gradefile.write("Wrong\n")
        gradefile.write("The total score is "+str(self.score))
        print 'The grade has been written to ./Grading/grade.txt'
        gradefile.close()

    def manualSel(self, answerfile, outputGradefile):    
        self.manualQuerylist()
        querylist = raw_input()
        self.readAnswerFileManual(answerfile)
        self.stuSpecQuery(querylist) 
        self.writeToGradeFile(outputGradefile)
        return

    def autoSel(self, answerfile, outputGradefile):    
        querylist = self.readAnswerFileAuto(answerfile)
        print querylist
        self.stuSpecQuery(querylist) 
        self.writeToGradeFile(outputGradefile)
        return

    def autograde(self, inputSpec, answerfile, outputGradefile):    
        print '**********************************************************'
        print '*                                                        *'
        print '*                    AUTO GRADING                        *'
        print '*                                                        *'
        print '**********************************************************'
        if os.path.exists('./Grading') is False:
            print 'Please make sure there is a \'Grading\' folder under current directory containing correct answer file!'
            return
        print 'Please choose the mode below:'
        print '1. Run query chosen in ./Grading/answerFileAuto.txt'
        print '2. Select query from list'
        self.grademode = raw_input()
        if self.grademode == '1':
            self.ioHelper.import_(inputSpec)
            self.autoSel(answerfile, outputGradefile) 
        elif self.grademode == '2':
            self.ioHelper.import_(inputSpec)
            self.manualSel(answerfile, outputGradefile)
        return
