package tech.easyflow.ai.easyagentsflow.repository;

import com.alicp.jetcache.Cache;
import com.alicp.jetcache.CacheException;
import com.alicp.jetcache.CacheResult;
import com.alicp.jetcache.CacheResultCode;
import org.junit.Assert;
import org.junit.Test;

import java.lang.reflect.Field;
import java.lang.reflect.Proxy;

/**
 * {@link BaseRepository} 缓存操作语义回归测试。
 */
public class BaseRepositoryTest {

    /**
     * 验证删除不存在的缓存键按幂等成功处理。
     *
     * @throws Exception 测试依赖注入失败时抛出
     */
    @Test
    public void removeCacheShouldAcceptMissingKey() throws Exception {
        TestRepository repository = repository(
                new CacheResult(CacheResultCode.NOT_EXISTS, null));

        repository.remove("missing-key");
    }

    /**
     * 验证真实删除错误仍会向上抛出。
     *
     * @throws Exception 测试依赖注入失败时抛出
     */
    @Test
    public void removeCacheShouldRejectOperationFailure() throws Exception {
        TestRepository repository = repository(
                new CacheResult(CacheResultCode.FAIL, "redis unavailable"));

        try {
            repository.remove("failed-key");
            Assert.fail("cache failure should be propagated");
        } catch (CacheException expected) {
            Assert.assertTrue(expected.getMessage().contains("failed-key"));
            Assert.assertTrue(expected.getMessage().contains("redis unavailable"));
        }
    }

    /**
     * 创建注入指定删除结果的测试仓储。
     *
     * @param removeResult 删除操作结果
     * @return 测试仓储
     * @throws Exception 反射注入失败时抛出
     */
    private TestRepository repository(CacheResult removeResult) throws Exception {
        Cache<String, Object> cache = cache(removeResult);
        TestRepository repository = new TestRepository();
        Field field = BaseRepository.class.getDeclaredField("cache");
        field.setAccessible(true);
        field.set(repository, cache);
        return repository;
    }

    /**
     * 创建只支持删除操作的 JetCache 代理。
     *
     * @param removeResult 删除操作结果
     * @return JetCache 测试代理
     */
    @SuppressWarnings("unchecked")
    private Cache<String, Object> cache(CacheResult removeResult) {
        return (Cache<String, Object>) Proxy.newProxyInstance(
                Cache.class.getClassLoader(),
                new Class<?>[]{Cache.class},
                (proxy, method, args) -> {
                    if ("REMOVE".equals(method.getName())) {
                        return removeResult;
                    }
                    throw new UnsupportedOperationException(
                            "unsupported cache method: " + method.getName());
                });
    }

    /**
     * 暴露受保护缓存删除能力的测试仓储。
     */
    private static final class TestRepository extends BaseRepository {

        /**
         * 删除指定缓存键。
         *
         * @param key 缓存键
         */
        private void remove(String key) {
            removeCache(key);
        }
    }
}
