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.QuestionSubmitRequestDTO;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Component;

/**
 * 用户代码校验责任链处理器
 */
@Slf4j
@Component
public class CodeVerifyChain implements AbstractChianHandler<QuestionSubmitRequestDTO> {

	/**
	 * 最小代码长度（字符数）
	 */
	private static final int MIN_CODE_LENGTH = 10;

	/**
	 * 最大代码长度（字符数）- 10KB
	 */
	private static final int MAX_CODE_LENGTH = 10240;

	@Override
	public void handle(QuestionSubmitRequestDTO requestParam) {
		String code = requestParam.getCode();

		// 校验代码不为空
		if (StringUtils.isBlank(code)) {
			throw new ClientException("代码不能为空", ErrorCode.PARAMS_ERROR);
		}

		// 去除首尾空白后重新校验
		String trimmedCode = code.trim();
		if (trimmedCode.isEmpty()) {
			throw new ClientException("代码不能为空", ErrorCode.PARAMS_ERROR);
		}

		// 校验代码长度
		if (trimmedCode.length() < MIN_CODE_LENGTH) {
			throw new ClientException(
				String.format("代码长度不能少于 %d 个字符", MIN_CODE_LENGTH),
				ErrorCode.PARAMS_ERROR
			);
		}

		if (trimmedCode.length() > MAX_CODE_LENGTH) {
			throw new ClientException(
				String.format("代码长度不能超过 %d 个字符", MAX_CODE_LENGTH),
				ErrorCode.PARAMS_ERROR
			);
		}

		// 安全检查：检测危险代码模式（根据需要扩展）
		String[] dangerousPatterns = {
			"Runtime.getRuntime().exec",
			"ProcessBuilder",
			"System.exec",
			"<script",
			"eval("
		};

		for (String pattern : dangerousPatterns) {
			if (trimmedCode.contains(pattern)) {
				log.warn("检测到危险代码模式: {}", pattern);
				// 根据业务需求，可以选择：
				// 1. 直接拒绝：throw new ClientException("代码包含危险操作", ErrorCode.FORBIDDEN_ERROR);
				// 2. 记录警告但允许通过
			}
		}

		log.debug("代码校验通过，代码长度: {} 字符", trimmedCode.length());
	}

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

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