package com.mosquito.project.permission;

import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;

import static org.junit.jupiter.api.Assertions.*;

/**
 * 权限码解析器单元测试
 * 验证PRD权限语义码的别名映射是否正确
 */
@DisplayName("权限码解析器测试")
class PermissionCodeResolverTest {

    private PermissionCodeResolver resolver;

    @BeforeEach
    void setUp() {
        resolver = new PermissionCodeResolver();
    }

    // ============== PRD审批执行权限测试 ==============

    @Test
    @DisplayName("approval.execute.approve 应解析为 approval.execute.approve.ALL")
    void testApprovalExecuteApprove() {
        String result = resolver.resolve("approval.execute.approve");
        assertEquals("approval.execute.approve.ALL", result);
    }

    @Test
    @DisplayName("approval.execute.reject 应解析为 approval.execute.reject.ALL")
    void testApprovalExecuteReject() {
        String result = resolver.resolve("approval.execute.reject");
        assertEquals("approval.execute.reject.ALL", result);
    }

    @Test
    @DisplayName("approval.execute.transfer 应解析为 approval.execute.transfer.ALL")
    void testApprovalExecuteTransfer() {
        String result = resolver.resolve("approval.execute.transfer");
        assertEquals("approval.execute.transfer.ALL", result);
    }

    // ============== PRD用户权限管理测试 ==============

    @Test
    @DisplayName("permission.user.assign 应解析为 permission.user.assign.ALL")
    void testPermissionUserAssign() {
        String result = resolver.resolve("permission.user.assign");
        assertEquals("permission.user.assign.ALL", result);
    }

    @Test
    @DisplayName("permission.user.revoke 应解析为 permission.user.revoke.ALL")
    void testPermissionUserRevoke() {
        String result = resolver.resolve("permission.user.revoke");
        assertEquals("permission.user.revoke.ALL", result);
    }

    // ============== PRD数据权限配置测试 ==============

    @Test
    @DisplayName("permission.data.config 应解析为 permission.data.config.ALL")
    void testPermissionDataConfig() {
        String result = resolver.resolve("permission.data.config");
        assertEquals("permission.data.config.ALL", result);
    }

    // ============== 兼容性测试 ==============

    @Test
    @DisplayName("冒号格式别名应能正确解析")
    void testLegacyFormatAliases() {
        assertEquals("approval.index.handle.ALL", resolver.resolve("approval:handle"));
        assertEquals("activity.index.view.ALL", resolver.resolve("activity:view"));
        assertEquals("user.index.freeze.ALL", resolver.resolve("user:freeze"));
    }

    @Test
    @DisplayName("四段式格式应保持不变")
    void testPrdFormatPreserved() {
        assertEquals("activity.index.view.ALL", resolver.resolve("activity.index.view.ALL"));
        assertEquals("approval.execute.approve.ALL", resolver.resolve("approval.execute.approve.ALL"));
    }

    // ============== matches方法测试 ==============

    @Test
    @DisplayName("matches方法应能正确匹配别名与规范格式")
    void testMatches() {
        // 别名与规范格式匹配
        assertTrue(resolver.matches("approval.execute.approve", "approval.execute.approve.ALL"));
        assertTrue(resolver.matches("permission.user.assign", "permission.user.assign.ALL"));
        assertTrue(resolver.matches("permission.data.config", "permission.data.config.ALL"));

        // 冒号格式与规范格式匹配
        assertTrue(resolver.matches("approval:handle", "approval.index.handle.ALL"));
    }

    // ============== extractDataScope测试 ==============

    @Test
    @DisplayName("extractDataScope应正确提取数据权限范围")
    void testExtractDataScope() {
        assertEquals("ALL", resolver.extractDataScope("approval.execute.approve"));
        assertEquals("ALL", resolver.extractDataScope("permission.user.assign"));
        assertEquals("ALL", resolver.extractDataScope("permission.data.config"));
    }

    // ============== 无scope与.ALL兼容测试 ==============

    @Test
    @DisplayName("isScopeLessFormat应正确识别三段式权限码")
    void testIsScopeLessFormat() {
        assertTrue(resolver.isScopeLessFormat("dashboard.chart.realtime"));
        assertTrue(resolver.isScopeLessFormat("risk.block.execute"));
        assertTrue(resolver.isScopeLessFormat("user.tag.add"));
        assertTrue(resolver.isScopeLessFormat("activity.index.view")); // 三段式也是无scope

        assertFalse(resolver.isScopeLessFormat("dashboard.chart.realtime.ALL"));
        assertFalse(resolver.isScopeLessFormat("activity.index.view.ALL"));
    }

    @Test
    @DisplayName("toAllScopeFormat应正确转换为带ALL的格式")
    void testToAllScopeFormat() {
        assertEquals("dashboard.chart.realtime.ALL", resolver.toAllScopeFormat("dashboard.chart.realtime"));
        assertEquals("risk.block.execute.ALL", resolver.toAllScopeFormat("risk.block.execute"));
        assertEquals("user.tag.add.ALL", resolver.toAllScopeFormat("user.tag.add"));

        // 已经是规范格式应保持不变
        assertEquals("activity.index.view.ALL", resolver.toAllScopeFormat("activity.index.view.ALL"));
    }

    @Test
    @DisplayName("toScopeLessFormat应正确转换为无scope格式")
    void testToScopeLessFormat() {
        assertEquals("dashboard.chart.realtime", resolver.toScopeLessFormat("dashboard.chart.realtime.ALL"));
        assertEquals("risk.block.execute", resolver.toScopeLessFormat("risk.block.execute.ALL"));
        assertEquals("user.tag.add", resolver.toScopeLessFormat("user.tag.add.ALL"));

        // 已经是三段式应保持不变
        assertEquals("dashboard.chart.realtime", resolver.toScopeLessFormat("dashboard.chart.realtime"));
    }

    @Test
    @DisplayName("无scope权限码与带ALL权限码应能互相匹配")
    void testScopeLessAndAllMatching() {
        // 无scope -> 带ALL
        assertEquals("dashboard.chart.realtime.ALL", resolver.toAllScopeFormat("dashboard.chart.realtime"));

        // 带ALL -> 无scope
        assertEquals("dashboard.chart.realtime", resolver.toScopeLessFormat("dashboard.chart.realtime.ALL"));

        // 循环转换应保持一致
        String original = "risk.block.execute";
        String withAll = resolver.toAllScopeFormat(original);
        String backToOriginal = resolver.toScopeLessFormat(withAll);
        assertEquals(original, backToOriginal);
    }
}
