package cn.com.qmth.stmms.biz.utils;

import java.text.ParseException;
import java.util.HashSet;
import java.util.Map.Entry;
import java.util.Set;

import cn.com.qmth.stmms.biz.exam.model.Marker;

import com.google.common.collect.HashMultimap;
import com.google.common.collect.Multiset;
import com.google.common.collect.SetMultimap;


/**
 * Redis zset替代方案，单JVM内部针对已领取未给分任务的管理工具
 * 
 * @author luoshi
 * 
 */
public class CurrentTaskUtil {

    private static SetMultimap<String, TaskEntry> taskMap = HashMultimap.create();
    

    /**
     * 尝试领取某个任务
     * 
     * @param marker
     * @param libraryId
     * @return
     */
    public static boolean add(Marker marker, int libraryId) {
        String key = getKey(marker.getExamId(), marker.getSubjectCode());
        TaskEntry obj = new TaskEntry(marker.getId(), libraryId);

        synchronized (CurrentTaskUtil.class) {
            if (taskMap.containsEntry(key, obj)) {
                return false;
            } else {
                taskMap.put(key, obj);
                return true;
            }
        }
    }

    /**
     * 删除某个已完成的任务
     * 
     * @param marker
     * @param libraryId
     */
    public static void remove(Marker marker, int libraryId) {
        TaskEntry obj = new TaskEntry(marker.getId(), libraryId);
        synchronized (CurrentTaskUtil.class) {
          taskMap.remove(getKey(marker.getExamId(), marker.getSubjectCode()), obj);
        }
    }

    /**
     * 某个科目已领取未给分的任务总数
     * 
     * @param examId
     * @param subjectCode
     * @return
     */
    public static int count(int examId, String subjectCode) {
        Set<TaskEntry> set = taskMap.get(getKey(examId, subjectCode));
        return set != null ? set.size() : 0;
    }

    /**
     * 某个评卷员已领取未给分的任务总数
     * 
     * @param marker
     * @return
     */
    public static int count(Marker marker) {
        Set<TaskEntry> set = taskMap.get(getKey(marker.getExamId(), marker.getSubjectCode()));
        int count = 0;
        if (set != null) {
            for (TaskEntry obj : set) {
                if (obj.markerId == marker.getId()) {
                    count++;
                }
            }
        }
        return count;
    }

    /**
     * 清除某个科目已领取未给分的任务
     * 
     * @param examId
     * @param subjectCode
     */
    public static void clear(int examId, String subjectCode) {
        synchronized (CurrentTaskUtil.class) {
            taskMap.removeAll(getKey(examId, subjectCode));
        }
    }

    /**
     * 清除某个评卷员已领取未给分的任务
     * 
     * @param marker
     */
    public static void clear(Marker marker) {
        String key = getKey(marker.getExamId(), marker.getSubjectCode());
        Set<TaskEntry> set = new HashSet<TaskEntry>();
        synchronized (CurrentTaskUtil.class) {
            set.addAll(taskMap.get(getKey(marker.getExamId(), marker.getSubjectCode())));
            for (TaskEntry obj : set) {
                if (obj.markerId == marker.getId()) {
                    taskMap.remove(key, obj);
                }
            }
        }
    }

    private static String getKey(int examId, String subjectCode) {
    	
        return examId + "_" + subjectCode;
    }
    
    public static void QuartzClearMap(long cleanMapinterval){
    	synchronized (CurrentTaskUtil.class) {
    		SetMultimap<String, TaskEntry> taskMap1 = HashMultimap.create();
//    		System.out.println("任务池大小："+taskMap.size());
//    		System.out.println("间隔时间："+cleanMapinterval);
			if(taskMap != null && taskMap.size()>0){
					Multiset<String> keysTemp = taskMap.keys();
					Set <String> setKey = new HashSet<String>();
					for(String key : keysTemp){
						setKey.add(key);
					}
					for(String key : setKey){
						Set<TaskEntry> set = taskMap.get(key);
						if (set != null) {
							for (TaskEntry obj : set) {
								if(getDateDifference(obj.timestamp)>=cleanMapinterval){//如果相隔20分钟，则该试卷的放入清空池中
									taskMap1.put(key, obj);
								}
							}
					}
				}
			}
			for(Entry<String, TaskEntry> taskEntry : taskMap1.entries()){
				taskMap.remove(taskEntry.getKey(), taskEntry.getValue());
			}
			taskMap1.clear();
		}
    }
	/**
	 * 获取当前时间戳
	 * @return
	 * @throws ParseException
	 */
	public static  Long getDateString(){
		return System.currentTimeMillis();
	}
	/**
	 * 时间戳相隔分钟
	 * @return
	 * @throws ParseException
	 */
	public static Long getDateDifference(Long oldTime){
		return  (getDateString() - oldTime) / (1000 * 60);
	}
}
class TaskEntry {
    public int markerId;

    public int libraryId;
    
    public long timestamp;

    public TaskEntry(int markerId, int libraryId) {
        this.markerId = markerId;
        this.libraryId = libraryId;
        this.timestamp = System.currentTimeMillis();
    }

    @Override
    public int hashCode() {
        return libraryId;
    }

    @Override
    public String toString() {
        return markerId + "-" + libraryId;
    }

    @Override
    public boolean equals(Object obj) {
        if (obj != null && obj instanceof TaskEntry) {
            TaskEntry mt = (TaskEntry) obj;
            return mt.libraryId == this.libraryId;
        } else {
            return false;
        }
    }
}

