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

import cn.com.qmth.stmms.biz.exam.model.MarkGroup;
import cn.com.qmth.stmms.biz.exam.model.Marker;
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.model.MarkLibrary;
import cn.com.qmth.stmms.biz.mark.model.TrialLibrary;
import cn.com.qmth.stmms.biz.mark.service.MarkLibraryService;
import cn.com.qmth.stmms.biz.mark.service.MarkService;
import cn.com.qmth.stmms.biz.mark.service.TrialService;
import cn.com.qmth.stmms.common.enums.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.List;

public class MarkerResetThread implements Runnable {

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

    private Marker marker;

    private MarkGroup group;

    private MarkService markService;

    private LockService lockService;

    private MarkLibraryService markLibraryService;

    private TrialService trialLibraryService;

    private MarkerService markerService;

    private MarkGroupService markGroupService;

    public MarkerResetThread(Marker marker, MarkGroup group, MarkService markService,
            MarkLibraryService markLibraryService, TrialService trialLibraryService, MarkerService markerService,
            MarkGroupService markGroupService, LockService lockService) {
        this.marker = marker;
        this.group = group;
        this.markService = markService;
        this.markLibraryService = markLibraryService;
        this.trialLibraryService = trialLibraryService;
        this.markerService = markerService;
        this.markGroupService = markGroupService;
        this.lockService = lockService;
    }

    @Override
    public void run() {
        if (marker == null) {
            return;
        }
        if (group == null) {
            return;
        }
        try {
            lockService.watch(LockType.EXAM_SUBJECT, marker.getExamId(), marker.getSubjectCode());
            lockService.watch(LockType.GROUP, marker.getExamId(), marker.getSubjectCode(), marker.getGroupNumber());
            lockService.waitlock(LockType.MARKER, marker.getId());
            group = markGroupService.findOne(group.getExamId(), group.getSubjectCode(), group.getNumber());
            if (group.getStatus() == MarkStatus.FINISH) {
                return;
            }
            markService.markerLogout(marker);
            if (group.getStatus() == MarkStatus.FORMAL) {
                // 仲裁和等待仲裁的任务不被重置
                // 只选取评卷完成状态的记录重新检查
                // 遍历相关评卷任务的模式
                List<MarkLibrary> list = markLibraryService.findByMarkerIdAndStatusNotIn(marker.getId(),
                        LibraryStatus.ARBITRATED, LibraryStatus.WAIT_ARBITRATE, LibraryStatus.PROBLEM);
                for (MarkLibrary library : list) {
                    lockService.waitlock(LockType.STUDENT, library.getStudentId());
                    try {
                        markService.resetLibrary(library);
                    } finally {
                        lockService.unlock(LockType.STUDENT, library.getStudentId());
                    }
                }
            } else if (group.getStatus() == MarkStatus.TRIAL) {
                List<TrialLibrary> list = trialLibraryService.findLibraryByMarkerId(marker.getId());
                for (TrialLibrary library : list) {
                    lockService.waitlock(LockType.STUDENT, library.getStudentId());
                    markService.resetLibrary(library);
                    lockService.unlock(LockType.STUDENT, library.getStudentId());
                }
            }
            markerService.resetById(marker.getId());
            markService.updateMarkedCount(group);
        } catch (Exception e) {
            log.error("reset marker error", e);
        } finally {
            lockService.unlock(LockType.MARKER, marker.getId());
            lockService.unwatch(LockType.GROUP, marker.getExamId(), marker.getSubjectCode(), marker.getGroupNumber());
            lockService.unwatch(LockType.EXAM_SUBJECT, marker.getExamId(), marker.getSubjectCode());
            lockService.unlock(LockType.MARKER_RESET, marker.getId());
        }
    }

}
