package cn.com.qmth.stmms.admin.thread;

import java.util.List;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import cn.com.qmth.stmms.biz.exam.service.ExamQuestionService;
import cn.com.qmth.stmms.biz.exam.service.ExamStudentService;
import cn.com.qmth.stmms.biz.exam.service.InspectedService;
import cn.com.qmth.stmms.biz.exam.service.MarkGroupService;
import cn.com.qmth.stmms.biz.exam.service.MarkerService;
import cn.com.qmth.stmms.biz.lock.LockService;
import cn.com.qmth.stmms.biz.mark.service.MarkService;
import cn.com.qmth.stmms.common.enums.LockType;
import cn.com.qmth.stmms.common.enums.SubjectiveStatus;

public class SubjectiveCalculateThread implements Runnable {

    protected static Logger log = LoggerFactory.getLogger(SubjectiveCalculateThread.class);

    private MarkService markService;

    private ExamQuestionService questionService;

    private MarkGroupService groupService;

    private MarkerService markerService;

    private InspectedService inspectedService;

    private LockService lockService;

    private Integer examId;

    private String subjectCode;

    private ExamStudentService studentService;

    public SubjectiveCalculateThread(Integer examId, String subjectCode, MarkService markService,
            LockService lockService, ExamQuestionService questionService, MarkGroupService groupService,
            MarkerService markerService, InspectedService inspectedService, ExamStudentService studentService) {
        this.markService = markService;
        this.lockService = lockService;
        this.questionService = questionService;
        this.groupService = groupService;
        this.markerService = markerService;
        this.inspectedService = inspectedService;
        this.examId = examId;
        this.subjectCode = subjectCode;
        this.studentService = studentService;
    }

    @Override
    public void run() {
        try {
            lockService.waitlock(LockType.SCORE_CALCULATE, examId, subjectCode);
            lockService.waitlock(LockType.EXAM_SUBJECT, examId, subjectCode);
            log.info("SubjectiveCalculateThread examId=" + examId + " subjectCode=" + subjectCode);
            markerService.logoutByExamIdAndSubjectCodeAndGroupNumber(examId, subjectCode, null);
            // 未分组的题目
            long unGroupQuestionCount = questionService.countByExamIdAndSubjectAndObjectiveAndGroupNumberIsNull(examId,
                    subjectCode, false);
            // 考生整体状态与总分更新
            long groupCount = groupService.countByExamAndSubject(examId, subjectCode);
            List<Integer> studentList = studentService.findIdByExamIdAndSubjectCodeAndSubjectiveStatus(examId,
                    subjectCode, SubjectiveStatus.UNMARK, SubjectiveStatus.MARKED);
            for (Integer studentId : studentList) {
                lockService.waitlock(LockType.STUDENT, studentId);
                markService.checkStudentSubjective(studentId, groupCount, unGroupQuestionCount);
                lockService.unlock(LockType.STUDENT, studentId);
            }
            inspectedService.cancelBySubject(examId, subjectCode);
        } catch (Exception e) {
            log.error("SubjectiveCalculateThread error", e);
        } finally {
            lockService.unlock(LockType.EXAM_SUBJECT, examId, subjectCode);
            lockService.unlock(LockType.SCORE_CALCULATE, examId, subjectCode);
        }
    }
}
