import java.util.List;

import org.apache.ibatis.cache.CacheKey;

import lombok.extern.slf4j.Slf4j;
import net.sf.ehcache.Cache;
import net.sf.ehcache.CacheManager;

/**
 * MyBatis EHCache 관련 유틸 클래스
 *
 *   - mapperId + statementId 에 대하여 exactly equals 가 아니라 contains 임에 주의
 * 
 * @author STEVE
 */
@Slf4j
public class MyBatisCacheUtil {

    /**
     * MyBatis 쿼리 캐시 제거
     * 
     * @param mapperId (e.g. "com.example.repository.UserRepository")
     * @param statementId (e.g. "findUserList")
     */
    @SuppressWarnings("unchecked")
    public static void evictCache(String mapperId, String statementId) {
    	
        CacheManager cacheManager = CacheManager.getCacheManager(CacheManager.DEFAULT_NAME);
        Cache cache = cacheManager.getCache(mapperId);
//        log.debug("## cache: {}", cache);
        
        if(cache == null) {
        	log.warn("## MyBatis cache [{}] 가 존재하지 않습니다.", mapperId);
        	return;
        }
        
        List<CacheKey> keys = cache.getKeys();
//        log.debug("## keys > length:[{}], contents:[{}]", keys.size(), keys);
    	
        String cacheKeySnippet = mapperId + "." + statementId;
        
        for(CacheKey key : keys) {
        	
        	String cacheKeyString = key.toString();
//        	log.debug("## cacheKeyString:[{}]", cacheKeyString);
        	
        	if(cacheKeyString.contains(cacheKeySnippet)) {
        		log.debug("## MyBatis cache 제거 대상 발견:[{}]", cacheKeySnippet);
        		boolean removeResult = cache.remove(key);
        		if(removeResult) {
        			log.debug("## MyBatis cache [{}] 가 제거되었습니다.", cacheKeySnippet);
        		} else {
        			log.debug("## MyBatis cache [{}] 제거에 실패하였습니다.", cacheKeySnippet);
        		}
        	}
        }
    }
    
}