package com.pj.project4sp.config;

import java.util.Arrays;
import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import com.pj.project4sp.SP;
import com.pj.utils.cache.RedisUtil;
import com.pj.utils.sg.AjaxError;
import com.pj.utils.sg.NbUtil;
import com.pj.utils.so.SoMap;

import cn.dev33.satoken.util.SaFoxUtil;

/**
 * 工具类：sp_config -- 配置信息表
 * @author click33 
 *
 */
@Component
public class SpConfigUtil {

	/** 底层 Mapper 对象 */
	public static SpConfigMapper spConfigMapper;
	@Autowired
	private void setSpConfigMapper(SpConfigMapper spConfigMapper) {
		SpConfigUtil.spConfigMapper = spConfigMapper;
	}
	
	// 校验一个配置项的配置名 是否重复 
	static void checkConfigName(SpConfig s) {
		AjaxError.notIsNull(s.getName(), "[ 配置项名 ] 不能为空");		// 验证: 配置名称 
		// 查的出来，并且其id和提供的参数id不一致，则证明已有旧记录存在 
		Long id2 = SP.publicMapper.getIdByWhere(SpConfig.TABLE_NAME, "name", s.getName());
		AjaxError.notTrue(id2 != null && (long)id2 != s.getId(), "该配置项已存在：" + s.getName());	
	}
	
	/** 
	 * 将一个 SpConfig 对象进行进行数据完整性校验 (方便add/update等接口数据校验)
	 */
	static void check(SpConfig s) {
		AjaxError.notIsNull(s.getGroupName(), "[ 配置分组 ] 不能为空");		// 验证: 配置分组 
		checkConfigName(s);
		// AjaxError.throwByIsNull(s.getValue(), "[ 配置项值 ] 不能为空");		// 验证: 配置值 
	}

	/** 
	 * 获取一个SpConfig (方便复制代码用) [G] 
	 */ 
	static SpConfig getSpConfig() {
		SpConfig s = new SpConfig();	// 声明对象 
		s.setId(0L);		// id号 
		s.setGroupName("");		// 配置分组 
		s.setName("");		// 配置名称 
		s.setValue("");		// 配置值 
		s.setRemarks("");		// 备注 
		s.setCreateTime("");		// 创建时间 
		s.setUpdateTime("");		// 更新时间 
		return s;
	}
	
	// ----------------- 快速获取配置 --------------------- 
	
	// 存储在 Reids 时使用的前缀 
	public static final String CONFIG_CACHE_PREFIX = "ssp:config:";
	
	/**
	 * 获取指定 name 配置项，获取不到时返回默认值 defaultValue 
	 */
	public static String getConfigValue(String name, String defaultValue) {
		// 先从 Redis 中获取 
		String value = RedisUtil.get(CONFIG_CACHE_PREFIX + name);
		
		// 如果 Reids 中不存在，则从数据库中查询，并塞进 Reids 中 
		if(value == null) {
			SpConfig config = spConfigMapper.getByName(name);
			if(config != null) {
				value = config.getValue();
				RedisUtil.set(CONFIG_CACHE_PREFIX + name, value);
			}
		}
		
		// 如果依然为null，说明尚未配置这个值，则返回调用者指定的默认值 
		if(value == null) {
			return defaultValue;
		}
		return value;
	}
	
	/**
	 * 清空指定 name 配置项的缓存 
	 */
	public static void clearCache(String name) {
		RedisUtil.del(CONFIG_CACHE_PREFIX + name); 
	}

	/**
	 * 获取常用配置项 
	 */
	public static SoMap getAppConfig() {
		List<String> names = Arrays.asList("isDynamicInfo", "appLogo", "appName", "appVersion", "appUpdateTime", "appIntro");
		List<SpConfig> list = spConfigMapper.getListByNames(names);
		SoMap so = new SoMap();
		for (SpConfig cfg : list) {
			so.set(cfg.getName(), cfg.getValue());
		}
		return so;
	}
	
	// --- 单项配置 
	
	/** 获取配置项：预留信息  */
	public static String reserveInfo() {
		return getConfigValue("reserveInfo", "");
	}

	/** 获取配置项：是否开放注册 */
	public static boolean isAllowRegister() {
		String value = getConfigValue("isAllowRegister", "");
		return SaFoxUtil.getValueByType(value, boolean.class);
	}

	/** 获取配置项：随机返回一个新用户头像地址 */
	public static String userDefaultAvatar() {
		String[] avatarArray = getConfigValue("userDefaultAvatar", "").split(",");
		int index = NbUtil.getRandom(0, avatarArray.length - 1);
		return avatarArray[index];
	}
	

	/** 获取配置项：是否打开 接收数据推送 */
	public static boolean isListen() {
		String value = getConfigValue("isListen", "");
		return SaFoxUtil.getValueByType(value, boolean.class);
	}

	/** 获取配置项：接收的数据是否使用SM4解密 */
	public static boolean isListenDecrypt() {
		String value = getConfigValue("isListenDecrypt", "");
		return SaFoxUtil.getValueByType(value, boolean.class);
	}

	/** 获取配置项：接收推送数据时允许的 IP 列表  */
	public static List<String> listenIpList() {
		return SaFoxUtil.convertStringToList(getConfigValue("listenIpList", ""));
	}

	/** 获取配置项：是否打开 向外发送广播 */
	public static boolean isBrd() {
		String value = getConfigValue("isBrd", "");
		return SaFoxUtil.getValueByType(value, boolean.class);
	}

	/** 获取配置项：广播的数据是否使用SM4加密 */
	public static boolean isBrdEncrypt() {
		String value = getConfigValue("isBrdEncrypt", "");
		return SaFoxUtil.getValueByType(value, boolean.class);
	}

	/** 获取配置项：向外广播，同步url */
	public static String brdUrlSync() {
		return getConfigValue("brdUrlSync", "");
	}

	/** 获取配置项：向外广播，同步url */
	public static List<String> brdUrl() {
		return SaFoxUtil.convertStringToList(getConfigValue("brdUrl", ""));
	}

	
}
