package tech.easyflow.system.service.impl;

import com.mybatisflex.core.query.QueryWrapper;
import org.junit.Assert;
import org.junit.Test;
import tech.easyflow.common.web.exceptions.BusinessException;
import tech.easyflow.system.entity.SysApiKey;

import java.util.Date;

/**
 * API Key 认证状态错误语义测试。
 */
public class SysApiKeyAuthenticationStatusTest {

    /**
     * 验证不存在的 API Key 使用 HTTP 401 语义。
     */
    @Test
    public void shouldReturnUnauthorizedWhenApiKeyMissing() {
        TestSysApiKeyService service = new TestSysApiKeyService(null);

        BusinessException error = expectBusinessException(
                () -> service.getSysApiKey("missing"));

        Assert.assertEquals(401, error.getHttpStatus());
        Assert.assertEquals(401, error.getErrorCode());
    }

    /**
     * 验证状态缺失的 API Key 按禁用处理并返回 HTTP 401。
     */
    @Test
    public void shouldReturnUnauthorizedWhenApiKeyStatusMissing() {
        SysApiKey apiKey = new SysApiKey();
        TestSysApiKeyService service = new TestSysApiKeyService(apiKey);

        BusinessException error = expectBusinessException(
                () -> service.getSysApiKey("status-missing"));

        Assert.assertEquals(401, error.getHttpStatus());
        Assert.assertEquals(401, error.getErrorCode());
    }

    /**
     * 验证过期的 API Key 使用 HTTP 401 语义。
     */
    @Test
    public void shouldReturnUnauthorizedWhenApiKeyExpired() {
        SysApiKey apiKey = new SysApiKey();
        apiKey.setStatus(1);
        apiKey.setExpiredAt(new Date(System.currentTimeMillis() - 1_000L));
        TestSysApiKeyService service = new TestSysApiKeyService(apiKey);

        BusinessException error = expectBusinessException(
                () -> service.getSysApiKey("expired"));

        Assert.assertEquals(401, error.getHttpStatus());
        Assert.assertEquals(401, error.getErrorCode());
    }

    /**
     * 执行调用并返回预期业务异常。
     *
     * @param action 待执行调用
     * @return 捕获的业务异常
     */
    private BusinessException expectBusinessException(Runnable action) {
        try {
            action.run();
            Assert.fail("expected BusinessException");
            return null;
        } catch (BusinessException error) {
            return error;
        }
    }

    /**
     * 固定返回 API Key 的测试服务。
     */
    private static final class TestSysApiKeyService
            extends SysApiKeyServiceImpl {

        private final SysApiKey apiKey;

        /**
         * 创建测试服务。
         *
         * @param apiKey 查询时返回的 API Key
         */
        private TestSysApiKeyService(SysApiKey apiKey) {
            this.apiKey = apiKey;
        }

        /**
         * 返回预设 API Key。
         *
         * @param queryWrapper 查询条件
         * @return 预设 API Key
         */
        @Override
        public SysApiKey getOne(QueryWrapper queryWrapper) {
            return apiKey;
        }
    }
}
