/**
 * Copyright 2008-2009. Chongqing Communications Industry Services Co.,Ltd Information Technology Branch. All rights reserved.
 * <a>http://www.crunii.com</a>
 */
package com.crunii.micro.service.sysmgr.service.impl;

import cn.hutool.core.text.TextSimilarity;
import cn.hutool.dfa.WordTree;
import com.crunii.micro.common.constants.CommonConstants;
import com.crunii.micro.common.constants.RedisKeys;
import com.crunii.micro.domain.entity.main.TsmMenu;
import com.crunii.micro.domain.entity.main.YcqAppConfigUrl;
import com.crunii.micro.domain.repo.main.TsmMenuRepo;
import com.crunii.micro.domain.repo.main.YcqAppConfigUrlRepo;
import com.google.common.cache.Cache;
import com.google.common.cache.CacheBuilder;
import lombok.extern.slf4j.Slf4j;
import org.redisson.api.RMapCache;
import org.redisson.api.RedissonClient;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.*;
import java.util.concurrent.TimeUnit;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * @author shenhs create 2023/5/23 15:27
 */
@Slf4j
@Component
public class TsmMenuCache implements InitializingBean {

	@Autowired
	private RedissonClient redisson;
	@Autowired
	private TsmMenuRepo repo;

	@Autowired
	private YcqAppConfigUrlRepo appConfigUrlRepo;

	private RMapCache<String, TsmMenu> menuRMapCache = null;
	// 这个Map的数据20秒内会过期
	private Cache<String, TsmMenu> timedCache = CacheBuilder.newBuilder().expireAfterWrite(20, TimeUnit.SECONDS).build();

	private RMapCache<String, YcqAppConfigUrl> appConfRMapCache = null;
	// 这个Map的数据20秒内会过期
	private Cache<String, YcqAppConfigUrl> appConfTimedCache = CacheBuilder.newBuilder().expireAfterWrite(20, TimeUnit.SECONDS).build();

	@Override public void afterPropertiesSet() throws Exception {
		if(menuRMapCache==null){
			menuRMapCache = redisson.getMapCache(RedisKeys.TSM_MENU_CACHE_KEY);
		}

		if(appConfRMapCache==null){
			appConfRMapCache = redisson.getMapCache(RedisKeys.TSM_APP_CONF_CACHE_KEY);
		}
		if(menuRMapCache.isEmpty() || appConfRMapCache.isEmpty()){
			load();
		}
	}

	public void load(){
		List<TsmMenu> all = repo.findByMenuTypeAndState(CommonConstants.MENU_TYPE_MENU,CommonConstants.STATE_VALID);
		Map<String, TsmMenu> collect = all.parallelStream().collect(Collectors.toMap(TsmMenu::getMenuUrl, Function.identity()));
		menuRMapCache.putAll(collect);
		log.info("加载tsm_menu缓存【{}】条",menuRMapCache.size());

		List<YcqAppConfigUrl> appAll = appConfigUrlRepo.findByState(CommonConstants.STATE_VALID);
		Map<String, YcqAppConfigUrl> appCollect = appAll.parallelStream().collect(Collectors.toMap(YcqAppConfigUrl::getAppUrl, Function.identity()));
		appConfRMapCache.putAll(appCollect);
		log.info("加载YcqAppConfigUrl缓存【{}】条", appConfRMapCache.size());
	}

	public TsmMenu get(String url){
		TsmMenu o = timedCache.getIfPresent(url);
		if(o==null){
			Map<String, TsmMenu> collect = menuRMapCache.values().parallelStream().collect(Collectors.toMap(TsmMenu::getMenuUrl, Function.identity()));
			timedCache.putAll(collect);
			return timedCache.getIfPresent(url);
		}
		return o;
	}

	public YcqAppConfigUrl getAppConf(String url){
		YcqAppConfigUrl o = appConfTimedCache.getIfPresent(url);
		if(o==null){
			Map<String, YcqAppConfigUrl> collect = appConfRMapCache.values().parallelStream().collect(Collectors.toMap(YcqAppConfigUrl::getAppUrl, Function.identity()));
			appConfTimedCache.putAll(collect);
			return appConfTimedCache.getIfPresent(url);
		}
		return o;
	}

	public Set<String> urlSet(){
		return menuRMapCache.keySet();
	}

	public Set<String> appUrlSet(){
		return appConfRMapCache.keySet();
	}

	public void reload(){
		menuRMapCache.clear();
		appConfRMapCache.clear();
		load();
	}
}
