package com.cirle.scientific.questionnaire.queue;

import com.cirle.scientific.questionnaire.dto.SubmitAnswerDTO;
import com.cirle.scientific.questionnaire.exception.AnswerSubmitException;
import com.cirle.scientific.questionnaire.exception.QuestionnaireNotFoundException;
import com.cirle.scientific.questionnaire.service.QuestionnaireService;

import java.util.Map;
import java.util.concurrent.BlockingQueue;

/**
 * 答案队列生产者（单例）
 */
public class AnswerProducer {

    private static AnswerProducer answerProducer;

    private final BlockingQueue<Map<String, SubmitAnswerDTO>> queue;

    private final QuestionnaireService questionnaireService;

    /**
     * 禁止外部实例化（单例）
     *
     * @param queue 队列对象
     */
    private AnswerProducer(BlockingQueue<Map<String, SubmitAnswerDTO>> queue, QuestionnaireService questionnaireService) {
        this.queue = queue;
        this.questionnaireService = questionnaireService;
    }

    /**
     * 初始化答案队列生产者
     *
     * @param queue 队列对象
     */
    public static void init(BlockingQueue<Map<String, SubmitAnswerDTO>> queue, QuestionnaireService questionnaireService) {
        if (answerProducer != null) {
            throw new IllegalStateException("该答案队列生产者已初始化");
        }
        answerProducer = new AnswerProducer(queue, questionnaireService);
    }

    /**
     * 获取答案队列生产者实例（单例）
     *
     * @return 答案队列生产者对象
     */
    public static AnswerProducer getInstance() {
        if (answerProducer == null) {
            throw new IllegalStateException("该答案队列生产者未初始化");
        }
        return answerProducer;
    }

    /**
     * 添加答案提交到队列中
     *
     * @param submitAnswerMap 以问卷ID作为Key、提交答案数据传输对象作为Value的Map对象
     * @throws AnswerSubmitException 当提交答案添加队列失败时抛出该异常
     */
    public void put(Map<String, SubmitAnswerDTO> submitAnswerMap) throws AnswerSubmitException {
        // 检查问卷是否存在
        try {
            for (Map.Entry<String, SubmitAnswerDTO> entry : submitAnswerMap.entrySet()) {
                questionnaireService.getQuestionnaire(entry.getKey());
            }
        } catch (QuestionnaireNotFoundException e) {
            throw new AnswerSubmitException(e);
        }
        // 添加到队列
        try {
            queue.put(submitAnswerMap);
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
            throw new AnswerSubmitException("添加到答案提交队列失败");
        }
    }

}