package org.matrix.actuators.env;

import cn.hutool.core.util.ReUtil;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.matrix.actuators.Actuator;
import org.matrix.database.entity.Environment;
import org.matrix.database.service.IEnvironmentService;
import org.matrix.exception.GlobalException;
import org.springframework.stereotype.Component;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Optional;

/**
 * EnvironmentActuator.
 *
 * @author Matrix <xhyrzldf@gmail.com>
 * @since 2022/1/21 at 4:19 PM
 * Suffering is the most powerful teacher of life.
 */
@Slf4j
@Component
@AllArgsConstructor
public class EnvironmentActuator implements Actuator {

    private final IEnvironmentService envService;

    /**
     * 用于正则找出形如#{id}这样的环境
     */
    public static final String ENV_VAR_EXP = "(#\\{(\\w*)})";

    /**
     * 替换掉SQL表达式中的形如#{id}这样的环境共享变量
     * <blockquote><pre>
     *     替换前 : select * from user where id = #{id}
     *     env的变量表 : key = id , value = 5
     *     替换后 : select * from user where id = 5
     * </pre></blockquote>
     *
     * @param sqlExp sql表达式
     * @param envId  环境共享变量
     * @return 替换后的字符串
     */
    public String replaceEnvVar(String sqlExp, Long envId) {
        // SQL表达式首先尝试替换掉形如#{name}的共享环境变量 todo 这里的env的map应该做一个缓存
        Environment env = Optional.of(envService.getById(envId))
                .orElseThrow(() -> new GlobalException("没有找到对应ID的example(env)对象,id = " + envId));
        Map<String, String> envMap = env.getVariable();
        List<String> envList = ReUtil.findAll(ENV_VAR_EXP, sqlExp, 2, new ArrayList<>());
        // 到对应env的变量池里找到值替换掉
        for (String key : envList) {
            if (envMap.containsKey(key)) {
                log.info("[变量替换] 将环境变量 {} 替换为 {}", String.format("#{%s}", key), envMap.get(key));
                sqlExp = sqlExp.replaceAll(String.format("#\\{%s}", key), envMap.get(key));
            } else {
                throw new GlobalException(String.format("id = %d 的环境(用例)表里没有key = %s 的数值,当前环境的变量池 = %s",
                        envId, key, envMap));
            }
        }
        return sqlExp;
    }
}
