package cn.com.qmth.stmms.biz.mark.service.Impl;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import cn.com.qmth.stmms.biz.exam.model.Exam;
import cn.com.qmth.stmms.biz.exam.model.ExamQuestion;
import cn.com.qmth.stmms.biz.exam.model.ExamStudent;
import cn.com.qmth.stmms.biz.exam.model.ExamSubject;
import cn.com.qmth.stmms.biz.exam.model.MarkGroup;
import cn.com.qmth.stmms.biz.exam.model.SelectiveGroup;
import cn.com.qmth.stmms.biz.exam.model.SubjectiveScore;
import cn.com.qmth.stmms.biz.exam.service.ExamQuestionService;
import cn.com.qmth.stmms.biz.exam.service.ExamService;
import cn.com.qmth.stmms.biz.exam.service.ExamStudentService;
import cn.com.qmth.stmms.biz.exam.service.ExamSubjectService;
import cn.com.qmth.stmms.biz.exam.service.MarkGroupService;
import cn.com.qmth.stmms.biz.exam.service.MarkerService;
import cn.com.qmth.stmms.biz.exam.service.SelectiveGroupService;
import cn.com.qmth.stmms.biz.exam.service.SubjectiveScoreService;
import cn.com.qmth.stmms.biz.file.service.FileService;
import cn.com.qmth.stmms.biz.mark.dao.HeaderTagDao;
import cn.com.qmth.stmms.biz.mark.dao.HeaderTrackDao;
import cn.com.qmth.stmms.biz.mark.model.ArbitrateHistory;
import cn.com.qmth.stmms.biz.mark.model.HeaderTag;
import cn.com.qmth.stmms.biz.mark.model.HeaderTrack;
import cn.com.qmth.stmms.biz.mark.model.MarkLibrary;
import cn.com.qmth.stmms.biz.mark.model.MarkSpecialTag;
import cn.com.qmth.stmms.biz.mark.model.MarkStepDTO;
import cn.com.qmth.stmms.biz.mark.model.MarkTrack;
import cn.com.qmth.stmms.biz.mark.model.MarkerSpecialTagDTO;
import cn.com.qmth.stmms.biz.mark.model.MarkerTrackDTO;
import cn.com.qmth.stmms.biz.mark.model.RejectHistory;
import cn.com.qmth.stmms.biz.mark.model.SpecialTagDTO;
import cn.com.qmth.stmms.biz.mark.model.Task;
import cn.com.qmth.stmms.biz.mark.model.TrackDTO;
import cn.com.qmth.stmms.biz.mark.model.TrialLibrary;
import cn.com.qmth.stmms.biz.mark.model.TrialTag;
import cn.com.qmth.stmms.biz.mark.model.TrialTrack;
import cn.com.qmth.stmms.biz.mark.query.MarkLibrarySearchQuery;
import cn.com.qmth.stmms.biz.mark.service.MarkLibraryService;
import cn.com.qmth.stmms.biz.mark.service.MarkSpecialTagService;
import cn.com.qmth.stmms.biz.mark.service.MarkTrackService;
import cn.com.qmth.stmms.biz.mark.service.RejectHistoryService;
import cn.com.qmth.stmms.biz.mark.service.TaskService;
import cn.com.qmth.stmms.biz.mark.service.TrialService;
import cn.com.qmth.stmms.biz.user.service.UserService;
import cn.com.qmth.stmms.biz.utils.ScoreItem;
import cn.com.qmth.stmms.common.enums.ExamType;
import cn.com.qmth.stmms.common.enums.LibraryStatus;
import cn.com.qmth.stmms.common.enums.MarkStatus;
import cn.com.qmth.stmms.common.enums.SubjectiveStatus;

/**
 * 评卷任务服务实现
 *
 * @author LS
 */
@Service("taskService")
public class TaskServiceImpl implements TaskService {

    private static Logger log = LoggerFactory.getLogger(TaskServiceImpl.class);

    public static final double UN_SELECTIVE_SCORE = -1;

    @Autowired
    private MarkLibraryService libraryService;

    @Autowired
    private ExamStudentService studentService;

    @Autowired
    private ExamQuestionService questionService;

    @Autowired
    private MarkTrackService trackService;

    @Autowired
    private HeaderTrackDao headerTrackDao;

    @Autowired
    private MarkGroupService groupService;

    @Autowired
    private MarkSpecialTagService markSpecialTagService;

    @Autowired
    private HeaderTagDao headerTagDao;

    @Autowired
    private MarkerService markerService;

    @Autowired
    private TrialService trialService;

    @Autowired
    private ExamSubjectService subjectService;

    @Autowired
    private UserService userService;

    @Autowired
    private FileService fileService;

    @Autowired
    private ExamService examService;

    @Autowired
    private SubjectiveScoreService scoreService;

    @Autowired
    private SelectiveGroupService selectiveGroupService;

    @Autowired
    private RejectHistoryService rejectHistoryService;

    @Override
    public List<Task> findByQuery(MarkLibrarySearchQuery query) {
        List<Task> list = new LinkedList<Task>();
        query = libraryService.findByQuery(query);
        if (query.getCurrentCount() > 0) {
            for (MarkLibrary library : query.getResult()) {
                list.add(build(library));
            }
        }
        return list;
    }

    @Override
    public Task build(ArbitrateHistory history, MarkGroup group) {
        ExamStudent student = studentService.findByExamIdAndExamNumber(history.getExamId(), history.getExamNumber());
        Task task = new Task();
        task.setStudentId(history.getStudentId());
        task.setLibraryId(history.getId());
        task.setSecretNumber(history.getSecretNumber());
        task.setQuestionList(buildArbitrateStep(group, history));
        task.setSpecialTagList(getHeaderTagList(history.getStudentId(), group.getNumber()));
        task.setSliceUrls(fileService.getSliceUris(student.getExamId(), student.getSecretNumber(), 1,
                student.getSliceCount()));
        task.setSliceConfig(group.getPictureConfigList());
        task.setJsonUrl(fileService.getJsonUri(student.getExamId(), student.getSecretNumber()));
        if (StringUtils.isNotBlank(student.getObjectiveScoreList())) {
            task.setObjectiveScore(student.getObjectiveScore());
        }
        task.setMarkerTime(history.getUpdateTime());
        if (history.getTotalScore() != null) {
            task.setMarkerScore(history.getTotalScore());
        }
        return task;
    }

    private List<MarkStepDTO> buildArbitrateStep(MarkGroup group, ArbitrateHistory history) {
        List<MarkStepDTO> list = new LinkedList<MarkStepDTO>();
        List<ExamQuestion> sList = questionService.findByExamAndSubjectAndObjectiveAndGroupNumber(group.getExamId(),
                group.getSubjectCode(), false, group.getNumber());
        List<HeaderTrack> tracks = headerTrackDao.findByPkStudentIdAndGroupNumber(history.getStudentId(),
                group.getNumber());
        List<ScoreItem> sItems = new ArrayList<ScoreItem>();
        if (history != null) {
            sItems = history.getScoreItemList();
        }
        ExamSubject subject = subjectService.find(group.getExamId(), group.getSubjectCode());
        for (int i = 0; i < sList.size(); i++) {
            ExamQuestion question = sList.get(i);
            MarkStepDTO step = buildStep(question, subject.getDisplayQuestionName());
            if (history != null) {
                if (!sItems.isEmpty() && sItems.size() == sList.size()) {
                    step.setScore(sItems.get(i).getScore());
                }
                // 未选做
                if (history.getTotalScore() != null && history.getTotalScore() == UN_SELECTIVE_SCORE) {
                    step.setScore(UN_SELECTIVE_SCORE);
                }
                // 增加阅卷轨迹列表获取
                String questionNumber = question.getQuestionNumber();
                for (HeaderTrack track : tracks) {
                    if (track.getQuestionNumber().equals(questionNumber)) {
                        step.addTrack(new TrackDTO(track));
                    }
                }
            }
            list.add(step);
        }
        return list;
    }

    @Override
    public Task build(MarkLibrary library) {
        Exam exam = examService.findById(library.getExamId());
        ExamSubject subject = subjectService.find(library.getExamId(), library.getSubjectCode());
        ExamStudent student = studentService.findByExamIdAndExamNumber(library.getExamId(), library.getExamNumber());
        MarkGroup group = groupService.findOne(library.getExamId(), library.getSubjectCode(), library.getGroupNumber());

        Task task = new Task();
        task.setLibraryId(library.getId());
        task.setStudentId(library.getStudentId());
        task.setSecretNumber(library.getSecretNumber());
        task.setStudentCode(student.getStudentCode());
        task.setStudentName(student.getName());
        task.setExamNumber(library.getExamNumber());
        task.setSubject(subject);
        if (ExamType.MULTI_MEDIA.equals(exam.getType())) {
            task.setJsonUrl(fileService.getJsonUri(library.getExamId(), library.getSecretNumber()));
        } else {
            task.setSliceUrls(fileService.getSliceUris(library.getExamId(), library.getSecretNumber(), 1,
                    student.getSliceCount()));
            task.setSliceConfig(group.getPictureConfigList());
            task.setSheetUrls(fileService.getSheetUris(library.getExamId(), library.getExamNumber(), 1,
                    student.getSheetCount()));
        }
        RejectHistory rejectHistory = rejectHistoryService.findLastByLibraryId(library.getId());
        task.setQuestionList(buildMarkStep(group, library, rejectHistory));
        task.setSpecialTagList(getMarkSpecialTagList(library.getId()));
        if (StringUtils.isNotBlank(student.getObjectiveScoreList())) {
            task.setObjectiveScore(student.getObjectiveScore());
        }
        task.setMarkerTime(library.getMarkerTime());
        if (library.getStatus() == LibraryStatus.REJECTED) {
            task.setRejected(true);
            task.setRejectReason(library.getRejectReason());
            if (exam.isShowReject()) {
                task.setRejectScoreList(rejectHistory == null ? null : rejectHistory.getScoreList());
            }
        }
        if (library.getStatus() == LibraryStatus.MARKED || library.getStatus() == LibraryStatus.INSPECTED) {
            task.setMarkerScore(library.getMarkerScore());
            task.setPrevious(true);
        }
        return task;
    }

    @Override
    public Task build(TrialLibrary library) {
        Exam exam = examService.findById(library.getExamId());
        ExamSubject subject = subjectService.find(library.getExamId(), library.getSubjectCode());
        ExamStudent student = studentService.findByExamIdAndExamNumber(library.getExamId(), library.getExamNumber());
        MarkGroup group = groupService.findOne(library.getExamId(), library.getSubjectCode(), library.getGroupNumber());

        Task task = new Task();
        task.setLibraryId(library.getId());
        task.setStudentId(library.getStudentId());
        task.setSecretNumber(library.getSecretNumber());
        task.setStudentCode(student.getStudentCode());
        task.setStudentName(student.getName());
        task.setExamNumber(library.getExamNumber());
        task.setSubject(subject);
        task.setQuestionList(buildTrialStep(group, library));
        if (StringUtils.isNotBlank(student.getObjectiveScoreList())) {
            task.setObjectiveScore(student.getObjectiveScore());
        }
        if (ExamType.MULTI_MEDIA.equals(exam.getType())) {
            task.setJsonUrl(fileService.getJsonUri(library.getExamId(), library.getSecretNumber()));
        } else {
            task.setSliceUrls(fileService.getSliceUris(library.getExamId(), library.getSecretNumber(), 1,
                    student.getSliceCount()));
            task.setSliceConfig(group.getPictureConfigList());
            task.setSheetUrls(fileService.getSheetUris(library.getExamId(), library.getExamNumber(), 1,
                    student.getSheetCount()));
        }
        if (library.getMarkerId() != null) {
            task.setSpecialTagList(getTrialTagList(library));
            task.setMarkerTime(library.getMarkerTime());
            task.setMarkerScore(library.getMarkerScore());
            task.setPrevious(true);
        }
        return task;
    }

    private List<MarkStepDTO> buildMarkStep(MarkGroup group, MarkLibrary library, RejectHistory rejectHistory) {
        List<MarkStepDTO> list = new LinkedList<MarkStepDTO>();
        List<ExamQuestion> sList = questionService.findByExamAndSubjectAndObjectiveAndGroupNumber(group.getExamId(),
                group.getSubjectCode(), false, group.getNumber());
        List<MarkTrack> tracks = new ArrayList<MarkTrack>();
        List<ScoreItem> sItems = new ArrayList<ScoreItem>();
        List<ScoreItem> rItems = null;
        if (library != null) {
            tracks = trackService.findByLibraryId(library.getId());
            sItems = library.getMarkerScoreItem();
        }
        if (rejectHistory != null) {
            rItems = rejectHistory.getRejectScoreItems();
        }
        ExamSubject subject = subjectService.find(group.getExamId(), group.getSubjectCode());
        for (int i = 0; i < sList.size(); i++) {
            ExamQuestion question = sList.get(i);
            MarkStepDTO step = buildStep(question, subject.getDisplayQuestionName());
            if (library != null) {
                if (!sItems.isEmpty() && sItems.size() == sList.size()) {
                    step.setScore(sItems.get(i).getScore());
                }
                if (rItems == null) {
                    // 无打回记录
                    step.setRejected(false);
                } else if (rItems != null && rItems.isEmpty()) {
                    // 全打回
                    step.setRejected(true);
                } else if (rItems != null && !rItems.isEmpty() && rItems.size() == sList.size()) {
                    // 部分打回
                    step.setRejected(rItems.get(i).getScore() == null);
                }
                // 未选做
                if (library.getMarkerScore() != null && library.getMarkerScore() == UN_SELECTIVE_SCORE) {
                    step.setScore(UN_SELECTIVE_SCORE);
                }
                // 增加阅卷轨迹列表获取
                String questionNumber = question.getQuestionNumber();
                for (MarkTrack track : tracks) {
                    if (track.getQuestionNumber().equals(questionNumber)) {
                        step.addTrack(new TrackDTO(track));
                    }
                }
            }
            list.add(step);
        }
        return list;
    }

    private List<MarkStepDTO> buildTrialStep(MarkGroup group, TrialLibrary library) {
        List<MarkStepDTO> list = new LinkedList<MarkStepDTO>();
        List<ExamQuestion> sList = questionService.findByExamAndSubjectAndObjectiveAndGroupNumber(group.getExamId(),
                group.getSubjectCode(), false, group.getNumber());
        List<TrialTrack> tracks = new ArrayList<TrialTrack>();
        List<ScoreItem> sItems = new ArrayList<ScoreItem>();
        if (library.getMarkerId() != null) {
            tracks = trialService.findTrack(library.getId());
            sItems = library.getScoreList();
        }
        ExamSubject subject = subjectService.find(group.getExamId(), group.getSubjectCode());
        for (int i = 0; i < sList.size(); i++) {
            ExamQuestion question = sList.get(i);
            MarkStepDTO step = buildStep(question, subject.getDisplayQuestionName());
            if (!sItems.isEmpty() && sItems.size() == sList.size()) {
                step.setScore(sItems.get(i).getScore());
            }
            if (library.getMarkerScore() != null && library.getMarkerScore() == UN_SELECTIVE_SCORE) {
                step.setScore(UN_SELECTIVE_SCORE);
            }
            // 增加阅卷轨迹列表获取
            String questionNumber = question.getQuestionNumber();
            for (TrialTrack track : tracks) {
                if (track.getQuestionNumber().equals(questionNumber)) {
                    step.addTrack(new TrackDTO(track));
                }
            }
            list.add(step);
        }
        return list;
    }

    private MarkStepDTO buildStep(ExamQuestion question, Boolean displayQuestionName) {
        MarkStepDTO step = new MarkStepDTO();
        step.setMainNumber(question.getMainNumber());
        step.setSubNumber(question.getSubNumber());
        if (displayQuestionName) {
            step.setQuestionName(question.getName());
        }
        step.setGroupNumber(question.getGroupNumber());
        step.setTitle(question.getMainTitle());
        step.setDefaultScore(0d);
        step.setMaxScore(question.getTotalScore());
        step.setMinScore(0d);
        step.setIntervalScore(question.getIntervalScore());
        step.setUncalculate(false);
        step.setSelectiveIndex(question.getSelectiveIndex());
        return step;
    }

    public SpecialTagDTO[] getHeaderTagList(Integer studentId, Integer groupNumber) {
        SpecialTagDTO[] specialTags = null;
        List<HeaderTag> list = headerTagDao.findByStudentIdAndGroupNumberOrderByIdAsc(studentId, groupNumber);
        if (!list.isEmpty()) {
            specialTags = new SpecialTagDTO[list.size()];
            for (int i = 0; i < list.size(); i++) {
                SpecialTagDTO specialTagDTO = new SpecialTagDTO(list.get(i));
                specialTags[i] = specialTagDTO;
            }
        }
        return specialTags;
    }

    public SpecialTagDTO[] getMarkSpecialTagList(Integer libraryId) {
        SpecialTagDTO[] specialTags = null;
        List<MarkSpecialTag> list = markSpecialTagService.findByLibraryId(libraryId);
        if (!list.isEmpty()) {
            specialTags = new SpecialTagDTO[list.size()];
            for (int i = 0; i < list.size(); i++) {
                SpecialTagDTO specialTagDTO = new SpecialTagDTO(list.get(i));
                specialTags[i] = specialTagDTO;
            }
        }
        return specialTags;
    }

    public SpecialTagDTO[] getTrialTagList(TrialLibrary library) {
        SpecialTagDTO[] specialTags = null;
        List<TrialTag> list = trialService.findTag(library.getId());
        if (!list.isEmpty()) {
            specialTags = new SpecialTagDTO[list.size()];
            for (int i = 0; i < list.size(); i++) {
                SpecialTagDTO specialTagDTO = new SpecialTagDTO(list.get(i));
                specialTags[i] = specialTagDTO;
            }
        }
        return specialTags;
    }

    @Override
    public Task build(ExamStudent student) {
        ExamSubject subject = subjectService.find(student.getExamId(), student.getSubjectCode());
        Exam exam = examService.findById(student.getExamId());

        Task task = new Task();
        task.setStudentId(student.getId());
        task.setSecretNumber(student.getSecretNumber());
        task.setStudentCode(student.getStudentCode());
        task.setStudentName(student.getName());
        task.setExamNumber(student.getExamNumber());
        task.setSubject(subject);
        if (ExamType.MULTI_MEDIA.equals(exam.getType())) {
            task.setJsonUrl(fileService.getJsonUri(student.getExamId(), student.getSecretNumber()));
        } else {
            task.setSliceUrls(fileService.getSliceUris(student.getExamId(), student.getSecretNumber(), 1,
                    student.getSliceCount()));
            task.setSheetUrls(fileService.getSheetUris(student.getExamId(), student.getExamNumber(), 1,
                    student.getSheetCount()));
        }
        if (!student.getSubjectiveStatus().equals(SubjectiveStatus.UNMARK)) {
            long trialGroupCount = groupService.countByExamAndSubjectAndStatus(student.getExamId(),
                    student.getSubjectCode(), MarkStatus.TRIAL);
            task.setQuestionList(buildMarkStep(student, trialGroupCount));
            task.setSpecialTagList(getMarkSpecialTagList(student, trialGroupCount));
            task.setHeaderTagList(getHeaderTagList(student));
        }
        if (StringUtils.isNotBlank(student.getObjectiveScoreList())) {
            task.setObjectiveScore(student.getObjectiveScore());
        }
        task.setMarkerScore(student.getTotalScore());
        task.setInspectTime(student.getInspectTime());
        return task;
    }

    private SpecialTagDTO[] getHeaderTagList(ExamStudent student) {
        List<HeaderTag> list = headerTagDao.findByStudentId(student.getId());
        SpecialTagDTO[] specialTags = new SpecialTagDTO[list.size()];
        for (int i = 0; i < list.size(); i++) {
            specialTags[i] = new MarkerSpecialTagDTO(list.get(i).getUserId(), list.get(i).getGroupNumber(), list.get(i));
        }
        return specialTags;
    }

    private SpecialTagDTO[] getMarkSpecialTagList(ExamStudent student, long trialGroupCount) {
        List<SpecialTagDTO> list = new LinkedList<>();
        if (trialGroupCount > 0) {
            List<TrialTag> tags = trialService.findTagByStudentId(student.getId());
            for (TrialTag trialTag : tags) {
                list.add(new SpecialTagDTO(trialTag));
            }
        } else {
            List<MarkGroup> groups = groupService.findByExamAndSubject(student.getExamId(), student.getSubjectCode());
            for (MarkGroup group : groups) {
                List<MarkLibrary> libraryList = libraryService
                        .findByStudentAndGroup(student.getId(), group.getNumber());
                // 不管单评还是多评显示所有评卷员特殊标记
                for (MarkLibrary library : libraryList) {
                    List<MarkSpecialTag> tagList = markSpecialTagService.findByLibraryId(library.getId());
                    for (MarkSpecialTag specialTag : tagList) {
                        list.add(new MarkerSpecialTagDTO(library.getMarkerId(), library.getGroupNumber(), specialTag));
                    }
                }
            }
        }
        return list.toArray(new SpecialTagDTO[0]);
    }

    private List<MarkStepDTO> buildMarkStep(ExamStudent student, long trialGroupCount) {
        List<MarkStepDTO> list = new LinkedList<MarkStepDTO>();
        List<ExamQuestion> sList = questionService.findByExamAndSubjectAndObjective(student.getExamId(),
                student.getSubjectCode(), false);
        Set<Integer> mainList = scoreService.findMainNumberByStudentIdAndUncalculate(student.getId(), true);
        List<SelectiveGroup> selectiveGroups = selectiveGroupService.findByExamIdAndSubjectCode(student.getExamId(),
                student.getSubjectCode());
        Map<Integer, SelectiveGroup> map = new HashMap<Integer, SelectiveGroup>();
        for (SelectiveGroup selectiveGroup : selectiveGroups) {
            map.put(selectiveGroup.getMainNumber(), selectiveGroup);
        }
        ExamSubject subject = subjectService.find(student.getExamId(), student.getSubjectCode());
        List<SubjectiveScore> scoreList = scoreService.findByStudentId(student.getId());
        // List<ScoreItem> sItems = student.getScoreList(false);
        for (int i = 0; i < scoreList.size(); i++) {
            ExamQuestion question = sList.get(i);
            String questionNumber = question.getQuestionNumber();
            if (map.containsKey(question.getMainNumber())) {
                question.setSelectiveIndex(map.get(question.getMainNumber()).getSelectiveIndex());
            }
            MarkStepDTO step = buildStep(question, subject.getDisplayQuestionName());
            if (!scoreList.isEmpty() && scoreList.size() == sList.size()) {
                step.setScore(scoreList.get(i).getScore());
                if (mainList.contains(step.getMainNumber())) {
                    step.setUncalculate(true);
                }
                step.setRejected(scoreList.get(i).getRejected());
            }
            // 增加阅卷轨迹列表获取
            if (trialGroupCount > 0) {
                List<TrialTrack> tracks = trialService.findTrackByStudentId(student.getId());
                for (TrialTrack track : tracks) {
                    if (track.getQuestionNumber().equals(questionNumber)) {
                        step.addTrack(new TrackDTO(track));
                    }
                }
            } else {
                // List<MarkLibrary> libraryList =
                // libraryService.findByStudentAndGroup(student.getId(),
                // question.getGroupNumber());
                // if (libraryList.size() == 1) {
                // List<MarkTrack> tracks =
                // trackService.findByStudentId(student.getId());
                List<MarkLibrary> libraryList = libraryService.findByStudentAndGroup(student.getId(),
                        question.getGroupNumber());
                // 不管单评还是多评显示所有评卷员给分轨迹
                for (MarkLibrary library : libraryList) {
                    List<MarkTrack> tracks = trackService.findByLibraryIdAndQuestionNumber(library.getId(),
                            questionNumber);
                    for (MarkTrack track : tracks) {
                        // if (track.getQuestionNumber().equals(questionNumber))
                        // {
                        // step.addTrack(new TrackDTO(track));
                        // }
                        step.addTrack(new MarkerTrackDTO(track));
                    }
                }
                // 仲裁轨迹
                List<HeaderTrack> headerTracks = headerTrackDao.findByPkStudentIdAndPkQuestionNumberOrderByPkNumberAsc(
                        student.getId(), questionNumber);
                for (HeaderTrack headerTrack : headerTracks) {
                    step.addHeaderTrack(new TrackDTO(headerTrack));
                }
            }
            list.add(step);
        }
        return list;
    }

    @Override
    public List<Task> findHistory(MarkLibrarySearchQuery query) {
        List<Task> list = new LinkedList<Task>();
        query = libraryService.findHistory(query);
        if (query.getCurrentCount() > 0) {
            for (MarkLibrary library : query.getResult()) {
                list.add(build(library));
            }
        }
        return list;
    }
}
