package cn.meowrain.aioj.backend.question.dto.chains;

import cn.meowrain.aioj.backend.framework.core.designpattern.chains.AbstractChianHandler;
import cn.meowrain.aioj.backend.framework.core.errorcode.ErrorCode;
import cn.meowrain.aioj.backend.framework.core.exception.ClientException;
import cn.meowrain.aioj.backend.question.common.enums.ChainMarkEnums;
import cn.meowrain.aioj.backend.question.dto.req.JudgeConfig;
import cn.meowrain.aioj.backend.question.dto.req.QuestionCreateRequestDTO;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

/**
 * 题目判题配置校验责任链处理器
 */
@Component
@Slf4j
public class QuestionJudgeConfigVerifyChain implements AbstractChianHandler<QuestionCreateRequestDTO> {

	/**
	 * 默认时间限制（毫秒）
	 */
	private static final Long DEFAULT_TIME_LIMIT = 3000L;

	/**
	 * 最大时间限制（毫秒）- 10秒
	 */
	private static final Long MAX_TIME_LIMIT = 10000L;

	/**
	 * 最小时间限制（毫秒）
	 */
	private static final Long MIN_TIME_LIMIT = 100L;

	/**
	 * 默认内存限制（MB）
	 */
	private static final Long DEFAULT_MEMORY_LIMIT = 256L;

	/**
	 * 最大内存限制（MB）- 1GB
	 */
	private static final Long MAX_MEMORY_LIMIT = 1024L;

	/**
	 * 最小内存限制（MB）
	 */
	private static final Long MIN_MEMORY_LIMIT = 16L;

	@Override
	public void handle(QuestionCreateRequestDTO requestParam) {
		JudgeConfig judgeConfig = requestParam.getJudgeConfig();

		// 判题配置可以为空，创建时使用默认值
		if (judgeConfig == null) {
			log.debug("判题配置为空，将使用默认值");
			return;
		}

		// 校验时间限制
		Long timeLimit = judgeConfig.getTimeLimit();
		if (timeLimit != null) {
			if (timeLimit < MIN_TIME_LIMIT) {
				throw new ClientException(
					String.format("时间限制不能小于 %d 毫秒", MIN_TIME_LIMIT),
					ErrorCode.PARAMS_ERROR
				);
			}
			if (timeLimit > MAX_TIME_LIMIT) {
				throw new ClientException(
					String.format("时间限制不能大于 %d 毫秒", MAX_TIME_LIMIT),
					ErrorCode.PARAMS_ERROR
				);
			}
		}

		// 校验内存限制
		Long memoryLimit = judgeConfig.getMemoryLimit();
		if (memoryLimit != null) {
			if (memoryLimit < MIN_MEMORY_LIMIT) {
				throw new ClientException(
					String.format("内存限制不能小于 %d MB", MIN_MEMORY_LIMIT),
					ErrorCode.PARAMS_ERROR
				);
			}
			if (memoryLimit > MAX_MEMORY_LIMIT) {
				throw new ClientException(
					String.format("内存限制不能大于 %d MB", MAX_MEMORY_LIMIT),
					ErrorCode.PARAMS_ERROR
				);
			}
		}

		log.debug("判题配置校验通过: timeLimit={}ms, memoryLimit={}MB",
			timeLimit != null ? timeLimit : DEFAULT_TIME_LIMIT,
			memoryLimit != null ? memoryLimit : DEFAULT_MEMORY_LIMIT);
	}

	@Override
	public String mark() {
		return ChainMarkEnums.QUESTION_CREATE_PARAM_VERIFY_CHAIN.getMark();
	}

	@Override
	public int getOrder() {
		return 40;
	}
}
