package cn.com.qmth.stmms.ms.marking.service;

import cn.com.qmth.stmms.ms.core.domain.Level;
import cn.com.qmth.stmms.ms.core.domain.MarkStage;
import cn.com.qmth.stmms.ms.core.domain.MarkSubject;
import cn.com.qmth.stmms.ms.core.domain.Paper;
import cn.com.qmth.stmms.ms.core.domain.task.MarkTask;
import cn.com.qmth.stmms.ms.core.domain.user.MarkUser;
import cn.com.qmth.stmms.ms.core.domain.user.Role;
import cn.com.qmth.stmms.ms.core.repository.*;
import cn.com.qmth.stmms.ms.core.vo.Subject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
import java.util.Random;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.stream.IntStream;

/**
 * 调试用
 * Created by dizhi on 2016/12/23.
 */
@Service
public class AutoRun {

    @Autowired
    private MarkUserRepo markUserRepo;

    @Autowired
    private MarkSubjectRepo markSubjectRepo;

    @Autowired
    private MarkTaskRepo markTaskRepo;

    @Autowired
    private LevelRepo levelRepo;

    @Autowired
    private MarkingService markingService;

    @Autowired
    private PaperRepo paperRepo;

    public void run(Long workId, Subject subject){
        MarkSubject markSubject = markSubjectRepo.findOne(workId + "-" + subject.toString());
        List<MarkUser> markers = markUserRepo.findByWorkIdAndSubjectAndRole(workId,subject, Role.MARKER);
        ExecutorService executor = Executors.newFixedThreadPool(markers.size());
        markers.forEach(m -> {
            executor.submit(this.buildTask(m,markSubject.getStage()));
        });
    }

    private Runnable buildTask(MarkUser marker,MarkStage markStage){
        List<MarkTask> markTasks =  markTaskRepo.findByMarkerIdAndStage(marker.getId(),markStage);
        Runnable task = null;
        if(markStage == MarkStage.LEVEL) {
            List<Level> levels = levelRepo.findByWorkId(marker.getWorkId());
            task = () -> {
                markTasks.forEach(t -> {
                    Random random = new Random();
                    int index = random.nextInt(levels.size());
                    markingService.levelMark(t, levels.get(index).getCode());
                });
            };
        }
        else if(markStage == MarkStage.SCORE){
            task = () -> {
                markTasks.forEach(t -> {
                    Paper paper = paperRepo.findOne(t.getPaper().getId());
                    Level level = levelRepo.findByWorkIdAndCode(marker.getWorkId(),paper.getLevel());
                    List<Integer> scores = new ArrayList<Integer>();
                    if(level.getLevelType() == Level.LevelType.ADMITED){
                        for (int i = level.getMinScore();i <= level.getMaxScore();i+= level.getIntervalScore()){
                            scores.add(i);
                        }
                    }
                    else{
                        String[] strs = level.getScoreList().split(",");
                        for(String s : strs){
                            scores.add(Integer.parseInt(s));
                        }
                    }
                    Random random = new Random();
                    int index = random.nextInt(scores.size());
                    markingService.scoring(t,scores.get(index));
                });
            };
        }

        return task;
    }
}
