# coding: utf-8
'''
Created on 16.02.2017

@author: d.gulyakin
'''

#from java.sql import Timestamp
from java.util import Date
from java.util import Calendar
from time import time
import json
from uuid import uuid4

from qt._qt_orm import TestingVariantAssignCursor, QtiVariantQuestionCursor, QtiVariantAnswerCursor,\
    QtiQuestionCursor, QtiDestructorCursor, \
    QtiVariantDestructorCursor, QtiVariantDestructorAnswerCursor,\
    QtiResourceCursor, QtiVariantParamsCursor
#    QtiVariantCursor, ContentCursor, QtiPackageAttributeCursor, \
#    Content_AttributeValueCursor, listAttributeContentCursor, \
    
#from qt.navigator import getAttributeValue
from ru.curs.celesta.showcase.utils import XMLJSONConverter
from qt.functions import completeTest, getImageById, getPrevNextQuestionId,\
    getAttributeValue
from fileRepository.functions import getRelativePathById

try:
    from ru.curs.showcase.core.jython import JythonDTO
    from ru.curs.showcase.core.jython import JythonDownloadResult
except:
    from ru.curs.celesta.showcase import JythonDTO

from qt.functions import getShowCorrectAnswerPermission


def cardData(context, main=None, add=None, filterinfo=None, session=None, elementId=None):
    u'''Карточка вопроса с одиночным выбором и для вопроса с множественным выбором. '''
    begin = time()
    session = json.loads(session)
    
    TVA = TestingVariantAssignCursor(context)
#    QtiVariant = QtiVariantCursor(context)
#    QtiPackageAttribute = QtiPackageAttributeCursor(context)
    QtiQuestion = QtiQuestionCursor(context)
    QtiVariantQuestion = QtiVariantQuestionCursor(context)
    QtiVariantAnswer = QtiVariantAnswerCursor(context)
    QtiDestructor = QtiDestructorCursor(context)
    QtiVariantDestructor = QtiVariantDestructorCursor(context)
    QtiVariantDestructorAnswer = QtiVariantDestructorAnswerCursor(context)
#     QtiResource = QtiResourceCursor(context)
#    Content = ContentCursor(context)
#    Content_Attribute = Content_AttributeValueCursor(context)
#    listAttributeContent = listAttributeContentCursor(context)
    
    variantQuestionId = main
    QtiVariantQuestion.get(variantQuestionId)
    variantId = QtiVariantQuestion.VariantID
    QtiVariantQuestion.setRange('VariantID',variantId)
    QtiVariantQuestion.orderBy('QuestionNumber')
    questionNumber = QtiVariantQuestion.QuestionNumber
    questionCount = QtiVariantQuestion.count()
    QtiQuestion.get(QtiVariantQuestion.QuestionID)
    print 'start', time() - begin
    #Получение содержания вопроса
    questionHtml = QtiQuestion.QuestionHtml if QtiQuestion.QuestionHtml is not None else ''
#    questionHtml2 = QtiQuestion.QuestionHtml2 if QtiQuestion.QuestionHtml2 is not None else ''
    questionImg = '/'.join(getRelativePathById(context, str(QtiQuestion.QuestionImg), file_version_id=None))
#     questionImg = getImageById(QtiResource,QtiQuestion.QuestionImg, isImage=False)
    print 'load', time() - begin

    #Проверка на то,  нужно ли отображать правильный ответ
    correctAnswerFlag = getShowCorrectAnswerPermission(context, session, variantId)

    print 'countquest', time() - begin
    TVA.get(variantId)
    if TVA.AlgorithmTestingID == 1:
        testingAlgorithm = u'Тестирование для самоконтроля'
    elif TVA.AlgorithmTestingID == 2:
        testingAlgorithm = u'Аудиторное тестирование'
    else:
        testingAlgorithm = u'Тестирование'
        
    questionHeader = u'Вопрос %s из %s'%(questionNumber,questionCount)
    print 'header', time() - begin
    
    
    #Получение идентификаторов предыдущего и следующего вопросов
#     QtiVariantQuestion.setRange("QuestionNumber",1)
#     QtiVariantQuestion.first()
#     
#     firstVariantQuestionId = QtiVariantQuestion.VariantQuestionID
#     
#     QtiVariantQuestion.setRange("QuestionNumber")
#     QtiVariantQuestion.get(variantQuestionId)
#     
#     nextVariantQuestionId = 'ID_FINISH'
#     if QtiVariantQuestion.navigate('>'):
#         nextVariantQuestionId = QtiVariantQuestion.VariantQuestionID
#     
#     prevVariantQuestionId = firstVariantQuestionId
#     QtiVariantQuestion.get(variantQuestionId)
#     if QtiVariantQuestion.navigate('<'):
#         prevVariantQuestionId = QtiVariantQuestion.VariantQuestionID
#         
    prevVariantQuestionId, nextVariantQuestionId = getPrevNextQuestionId(context, QtiVariantQuestion, variantQuestionId)
    QtiVariantQuestion.close()
        
    QtiVariantAnswer.setRange('VariantID',variantId)
    QtiVariantAnswer.first()
    
    #Тестирование завершилось или нет
    timeEnd = QtiVariantAnswer.TimeEnd
    timeout = '1' if QtiVariantAnswer.TimeEnd < Date() else '0'
    if QtiVariantAnswer.TimeFinish is None and QtiVariantAnswer.TimeEnd < Date():
        testingStatus = '2'
    elif QtiVariantAnswer.TimeFinish is not None:
        testingStatus = '1'
    else:
        testingStatus = '0'
    
    QtiVariantDestructor.setRange('VariantQuestionID',variantQuestionId)
    
    optionList = []
    resultList = []
    letter = ord('A')
    QtiVariantDestructor.orderBy('VariantDestructorID')
    print 'prequest', time() - begin
    
    #Получение вариантов ответа
    for QtiVariantDestructor in QtiVariantDestructor.iterate():
        QtiDestructor.get(QtiVariantDestructor.DestructorID)
        variantDestructorId = QtiVariantDestructor.VariantDestructorID
        destructorHtml = QtiDestructor.DestructorHtml if QtiDestructor.DestructorHtml is not None else ''
#        destructorHtml2 = QtiDestructor.DestructorHtml2 if QtiDestructor.DestructorHtml2 is not None else ''
        answerText = QtiDestructor.AnswerText if QtiDestructor.AnswerText is not None else ''
#        destructorImg =  getImageById(QtiResource,QtiDestructor.DestructorImg)

        correctFlag = False
        if correctAnswerFlag:
            if QtiDestructor.IsTrue:
                correctFlag = True        
        optionList.append({"id":variantDestructorId,
                            "letter": chr(letter),
                            "destructorHTML": destructorHtml, # + destructorImg + destructorHtml2,
                            "answerText": answerText,
                            "isTrue":'true' if correctFlag else 'false'
                            })

        checked = '1_' if testingStatus != '0' else '0_'
        
        #Проверям выбирал ли текущий вариант пользователь, когда в предыдущий раз отвечал на этот вопрос
        QtiVariantDestructorAnswer.setRange('VariantDestructorID',QtiVariantDestructor.VariantDestructorID)
        if QtiVariantDestructorAnswer.tryFirst():
            if QtiVariantDestructorAnswer.IsTrue:
                checked += '1'
            else:
                checked += '0'
        else:
            checked += '0'
        resultList.append({"@id": "variant{}".format(chr(letter)), "letter": chr(letter),"id":variantDestructorId, "checked":checked})
        letter += 1        
     
    print 'calcList', time() - begin
    calNow = Calendar.getInstance()
    timeNow = Date()
    calNow.setTime(timeNow)
    
    calEnd = Calendar.getInstance()
    calEnd.setTime(timeEnd)
    
    print 'quest', time() - begin
    #Скрипт, который вставляет счётчик оставшегося времени
    js = '''javascript: injectCounter(new Date(%s,%s,%s,%s,%s,%s),new Date(%s,%s,%s,%s,%s,%s));''' % \
    (calEnd.get(Calendar.YEAR),calEnd.get(Calendar.MONTH),calEnd.get(Calendar.DAY_OF_MONTH),\
     calEnd.get(Calendar.HOUR_OF_DAY),calEnd.get(Calendar.MINUTE),calEnd.get(Calendar.SECOND),\
     calNow.get(Calendar.YEAR),calNow.get(Calendar.MONTH),calNow.get(Calendar.DAY_OF_MONTH),\
     calNow.get(Calendar.HOUR_OF_DAY),calNow.get(Calendar.MINUTE),calNow.get(Calendar.SECOND))
    
    QtiVariantParams = QtiVariantParamsCursor(context)
    skipQuestions = getAttributeValue(QtiVariantParams, variantId, 'SkipQuestions')
    QtiVariantParams.close()
        
    xformsdata = {"schema": {
                    "@xmlns":"",
                    "description": {
                        "testingAlgorithm": testingAlgorithm,
                        "js":js,
                        "questionHeader":questionHeader,
                        "questionType":'7',
                        "skipQuestions": skipQuestions,
                        "question_img_file": questionImg,
                        "testingStatus": testingStatus,
                        "showCorrect": 'true' if correctAnswerFlag else 'false',
                        "captchaText":'',
                        "question":
                            {"@number": questionNumber,
                             "@isLastQuestion":'1' if nextVariantQuestionId == 'ID_FINISH' else '0',
                             "@timeout":timeout,
                            "#text":questionHtml# + questionImg + questionHtml2 + ']]>'
                             },
                        "options":{"option":optionList}
                       },
                    "result":{"option":resultList}}}
    #Переходы к следующему и предыдущему вопросам, завершению тестирования и списку вопросов
    xformssettings = {"properties":{
                        "event":[{
                            "@name":"single_click",
                            "@linkId": "1",
                            "action":{
                                "#sorted": [
                                    {"navigator":
                                        {"@element": prevVariantQuestionId}
                                    }]}
                             },
                             {"@name":"single_click",
                             "@linkId": "2",
                             "action":{
                                "#sorted": [
                                    {"navigator":
                                        {"@element": nextVariantQuestionId}
                                    }]}
                             },
                             {"@name":"single_click",
                             "@linkId": "3",
                             "action":{
                                "#sorted": [
                                    {"navigator":
                                        {"@element": "ID_FINISH"}
                                    }]}
                             },
                             {"@name":"single_click",
                             "@linkId": "4",
                             "action":{
                                "#sorted": [
                                    {"navigator":
                                        {"@element": "ID_CONTENTS"}}]}}]}}

    data = XMLJSONConverter.jsonToXml(json.dumps(xformsdata))
    data = data.replace('&nbsp;','&amp;nbsp;')
    settings = XMLJSONConverter.jsonToXml(json.dumps(xformssettings))

    print 'finish', time() - begin
    return JythonDTO(data, settings)


def cardDataSave(context, main=None, add=None, filterinfo=None, session=None, elementId=None, xformsdata=None):
    u'''Процедура сохранения ответа на вопрос. Для всех типов вопросов используется общая процедура сохранения'''
    session = json.loads(session)
    data = json.loads(xformsdata)

#     raise Exception(data)

    ip = session['sessioncontext']['ip']
    
    QtiVariantQuestion = QtiVariantQuestionCursor(context)
    QtiQuestion = QtiQuestionCursor(context)
    QtiVariantAnswer = QtiVariantAnswerCursor(context)
    QtiVariantDestructor = QtiVariantDestructorCursor(context)
    QtiVariantDestructorAnswer = QtiVariantDestructorAnswerCursor(context)
    
    variantQuestionId = main
    
    QtiVariantQuestion.get(variantQuestionId)
    QtiQuestion.get(QtiVariantQuestion.QuestionID)
    
    questionType = QtiQuestion.QuestionType
    variantId = QtiVariantQuestion.VariantID
    
    now = Date()
    
    QtiVariantAnswer.setRange('VariantID',variantId)
    QtiVariantAnswer.first()
    
    timeEnd = QtiVariantAnswer.TimeFinish if QtiVariantAnswer.TimeFinish is not None else QtiVariantAnswer.TimeEnd
    
    timeout = True if now > timeEnd else False
    #Если время тестирования завершилось, то ответ на текущий вопрос не сохраняем и завешаем тестирование
    if timeout:
        completeTest(context,variantId)
        return
    
    #Удаляем предыдущий ответ на вопрос
    QtiVariantDestructor.setRange('VariantQuestionID',variantQuestionId)
    for QtiVariantDestructor in QtiVariantDestructor.iterate():
        QtiVariantDestructorAnswer.setRange('VariantDestructorID',QtiVariantDestructor.VariantDestructorID)
        QtiVariantDestructorAnswer.deleteAll()
    
    
    if questionType in (1, 2, 7):
        #Для вопрсов с одиночным и множественным выбором в ответы пишутся идентификаторы выбранных вариантов
        optionsList = data['schema']['result']['option']
        
        if not isinstance(optionsList,list):
            optionsList = [optionsList]
        
        for option in optionsList:
            if option['checked'] == '0_1':
                QtiVariantDestructor.get(option['id'])
                QtiVariantDestructorAnswer.VariantDestructorAnswerID = unicode(uuid4())
                QtiVariantDestructorAnswer.VariantDestructorID = option['id']
                QtiVariantDestructorAnswer.IsTrue = True
                QtiVariantDestructorAnswer.AnswerIP = ip
                QtiVariantDestructorAnswer.insert()
    elif questionType == 3:
        #Для текстового вопрос записывается текст ответ в поле DestructorText
        variantDestructorId = data['schema']['result']['option']['@id']
        QtiVariantDestructorAnswer.VariantDestructorAnswerID = unicode(uuid4())
        QtiVariantDestructorAnswer.VariantDestructorID = variantDestructorId
        QtiVariantDestructorAnswer.DestructorText = data['schema']['result']['option']['answer']
        QtiVariantDestructorAnswer.IsTrue = True
        QtiVariantDestructorAnswer.AnswerIP = ip
        QtiVariantDestructorAnswer.insert()
    elif questionType in (4, 6):
        #Для соответствия и классификации в DestructorId пишутся какой вариант из правого столбца был выбран
        if 'option2' in data['schema']['result']:
            optionsList = data['schema']['result']['option2']
            if not isinstance(optionsList,list):
                optionsList = [optionsList]
            for option in optionsList:
                QtiVariantDestructorAnswer.VariantDestructorAnswerID = unicode(uuid4())
                QtiVariantDestructorAnswer.VariantDestructorID = option['@VariantDestructorID']
                QtiVariantDestructorAnswer.DestructorID = option['@DestructorID']
                QtiVariantDestructorAnswer.IsTrue = True
                QtiVariantDestructorAnswer.AnswerIP = ip
                QtiVariantDestructorAnswer.insert()
    elif questionType == 5:
        #Для сортировки в DestructorText пишется порядковый номер варианта
        if 'option2' in data['schema']['result']:
            optionsList = data['schema']['result']['option2']
            if not isinstance(optionsList,list):
                optionsList = [optionsList]
            for option in optionsList:
                QtiVariantDestructorAnswer.VariantDestructorAnswerID = unicode(uuid4())
                QtiVariantDestructorAnswer.VariantDestructorID = option['@id']
                QtiVariantDestructorAnswer.DestructorText = option['@text']
                QtiVariantDestructorAnswer.IsTrue = True
                QtiVariantDestructorAnswer.AnswerIP = ip
                QtiVariantDestructorAnswer.insert()