package cn.api.system;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import org.apache.commons.lang3.StringUtils;
import org.springframework.data.redis.core.RedisCallback;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import cn.facade.abs.IService;
import cn.common.annotation.Log;
import cn.common.enums.BizOpType;
import cn.common.enums.ResultCode;
import cn.common.exception.BusinessException;
import cn.common.page.response.Result;
import cn.constant.CommonConst;
import cn.monitor.core.Server;
import cn.monitor.model.OnlineUser;
import cn.pojo.entity.TSysDictData;
import cn.pojo.vo.LoginUser;
import cn.service.IOnlineUserService;
import cn.service.system.ICacheService;
import cn.util.core.IsKit;
import cn.util.core.LogKit;
import cn.util.core.TypeKit;
import javax.annotation.Resource;

/**应用系统专用或专门的方法*/
@RestController
@RequestMapping("/api/sys")
public class SysCtrl extends IService
{
	@Resource
	private ICacheService cacheService;
	@Resource
	private RedisTemplate<String, String> redisTemplate;
	@Resource
	private IOnlineUserService userOnlineService;

	/**Redis缓存监控信息*/
	@GetMapping("/getRedisCache")
	@Log(title = "系统监控-获取Redis缓存信息-getRedisCache", businessType = BizOpType.REDIS)
	public Result<?> getRedisCacheInfo()
	{
		Properties info = (Properties) redisTemplate.execute((RedisCallback<Object>) connection -> connection.info());
		Properties commandStats = (Properties) redisTemplate.execute((RedisCallback<Object>) connection -> connection.info("commandstats"));
		Object dbSize = redisTemplate.execute((RedisCallback<Object>) connection -> connection.dbSize());
		Map<String, Object> result = new HashMap<>(3);
		result.put("info", info);
		result.put("dbSize", dbSize);
		List<Map<String, String>> pieList = new ArrayList<>();
		commandStats.stringPropertyNames().forEach(key -> {
			Map<String, String> data = new HashMap<>(2);
			String property = commandStats.getProperty(key);
			data.put("name", StringUtils.removeStart(key, "cmdstat_"));
			data.put("value", StringUtils.substringBetween(property, "calls=", ",usec"));
			pieList.add(data);
		});
		result.put("commandStats", pieList);
		return Result.ok(result);
	}

	@GetMapping("/getServerInfo")
	@Log(title = "系统监控-获取服务器信息-getServerInfo", businessType = BizOpType.SERVER)
	public Result<?> getServerInfo() throws Exception
	{
		Server server = new Server();
		server.copyTo();
		return Result.ok(server);
	}

	/**获取当前在线用户 即UserDetailsImpl类内的内容
	 * 用户登陆时 相关信息写入缓存，这里检索缓存中所有用户
	 * */
	@GetMapping("/getOnLineUserList")
	@Log(title = "系统监控-获取在线用户-getOnLineUserList", businessType = BizOpType.ONLINE)
	public Result<?> getOnLineList(String ipaddr, String userName)
	{
		Collection<String> keys = redisCache.keys(CommonConst.LOGIN_TOKEN_KEY + "*");
		List<OnlineUser> userOnlineList = new ArrayList<>();
		for (String key : keys)
		{
			LoginUser user = (LoginUser) redisCache.getCacheObject(key);
			if (StringUtils.isNotEmpty(ipaddr) && StringUtils.isNotEmpty(userName))
			{
				if (StringUtils.equals(ipaddr, user.getIpaddr()) && StringUtils.equals(userName, user.getUsername())) {
					userOnlineList.add(userOnlineService.selectOnlineByInfo(ipaddr, userName, user));
				}
			} else if (StringUtils.isNotEmpty(ipaddr)) {
				if (StringUtils.equals(ipaddr, user.getIpaddr())) {
					userOnlineList.add(userOnlineService.selectOnlineByIpaddr(ipaddr, user));
				}
			} else if (StringUtils.isNotEmpty(userName) && IsKit.isNotNull(user.getUserMap())) {
				if (StringUtils.equals(userName, user.getUsername())) {
					userOnlineList.add(userOnlineService.selectOnlineByUserName(userName, user));
				}
			} else {
				userOnlineList.add(userOnlineService.loginUserToUserOnline(user));
			}
		}
		userOnlineList.removeAll(Collections.singleton(null));
		return Result.ok(userOnlineList);
	}
	/**强退用户. 问题： 是否主动通知？*/
	@DeleteMapping("/forceLogout/{tokenId}")
	@Log(title = "系统监控-强退用户-forceLogout", businessType = BizOpType.FORCE)
	public Result<?> forceLogout(@PathVariable String tokenId)
	{
		redisCache.deleteObject(CommonConst.LOGIN_TOKEN_KEY + tokenId);
		return Result.ok();
	}

	//**以下的操作涉及缓存根据字典类型t_sys_dict_type.dict_type查询表t_sys_dict_data中字典数据信息*/
	@GetMapping(value = "/getDictData/{dictType}")
	@Log(title = "系统操作-查询字典数据-getDictData", businessType = BizOpType.SELECT)
	public Result<?> getDictData(@PathVariable String dictType)
	{
		List<TSysDictData> data = cacheService.getDictDataByType(dictType);
		if (IsKit.isNull(data)) {
			return Result.ok(new ArrayList<>());
		}
		return Result.ok(cacheService.getDictDataByType(dictType));
	}

	/**清空指定缓存参数
	 * 参数管理cache key: sys_config:
	 * 字典管理cache key: sys_dict:
	 * */
	@DeleteMapping("/clearCache/{configKey}")
	@Log(title = "Redis管理-清除缓存信息-清空缓存参数配置", businessType = BizOpType.CLEAN)
	public Result<?> clearCache(@PathVariable String configKey)
	{   //CacheConst.SYS_CONFIG_KEY
		Collection<String> keys = redisCache.keys(configKey + ":*");
		redisCache.deleteObject(keys);
		return Result.ok();
	}

	/**目前：页面控制一次删除一条记录*/
	@DeleteMapping("/delNews/{tableName}/{dirName}")
	@Log(title = "公告管理-删除一条公告-delNews", businessType = BizOpType.DELETE)
	public Result<?> delNews(@PathVariable String tableName,
							 @PathVariable String dirName,@RequestBody List<String> idList)
	{
		int num = 0;
		for(String id: idList)
		{
			Boolean delFlag = true;
			try {
				delFlag = daoService.delById(tableName,id);
			} catch (BusinessException e) {
				LogKit.info(e);
			}
			if(delFlag) {
				Map<String, Object> paramMap = new HashMap<>();
				paramMap.put(CommonConst.DEFAULT_PRIMARY_KEY, id);
				//新闻内容news_content_wang
				Map<String, Object> resultMap = daoService.getMap(tableName,"news_content_wang",paramMap);
				List<String> srcList = fileService.getImgUrl(TypeKit.objToStr(resultMap.get("newsContentWang")));
				num = fileService.deleteFiles(dirName,srcList);
			}
		}
		if(num > 0) {
			return Result.ok();
		}
		else {
			return Result.warnMsg(ResultCode.SQL_DELETE.getMsg());
		}
	}
}