package com.ruoyi.web;

import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONReader;
import com.ruoyi.common.constant.Constants;
import com.ruoyi.common.core.domain.entity.SysDept;
import com.ruoyi.common.core.domain.entity.SysRole;
import com.ruoyi.common.core.domain.entity.SysUser;
import com.ruoyi.common.core.domain.model.LoginUser;
import com.ruoyi.framework.config.FastJson2JsonRedisSerializer;
import java.nio.charset.StandardCharsets;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;

class FastJson2LoginUserTest
{
    private static final String LEGACY_REDIS_JSON = "{\"@type\":\"com.ruoyi.common.core.domain.model.LoginUser\",\"browser\":\"Chrome 148\",\"deptId\":103L,\"expireTime\":1780482471190,\"ipaddr\":\"115.238.57.190\",\"loginLocation\":\"XX XX\",\"loginTime\":1780480671190,\"os\":\"Windows10\",\"permissions\":Set[\"*:*:*\"],\"token\":\"96dc6244-2273-489d-865f-36da1c8999bc\",\"user\":{\"createBy\":\"admin\",\"createTime\":\"2026-05-09 10:26:46\",\"delFlag\":\"0\",\"dept\":{\"ancestors\":\"0,100,101\",\"children\":[],\"deptId\":103L,\"deptName\":\"研发部门\",\"leader\":\"若依\",\"orderNum\":1,\"params\":{\"@type\":\"java.util.HashMap\"},\"parentId\":101L,\"status\":\"0\"},\"deptId\":103L,\"email\":\"ry@163.com\",\"loginDate\":\"2026-06-03 17:44:28\",\"loginIp\":\"115.238.57.190\",\"nickName\":\"超级管理员\",\"params\":{\"@type\":\"java.util.HashMap\"},\"phonenumber\":\"15888888888\",\"pwdUpdateDate\":\"2026-05-09 10:26:46\",\"remark\":\"管理员\",\"roles\":[{\"dataScope\":\"1\",\"deptCheckStrictly\":false,\"flag\":false,\"menuCheckStrictly\":false,\"params\":{\"@type\":\"java.util.HashMap\"},\"roleId\":1L,\"roleKey\":\"admin\",\"roleName\":\"超级管理员\",\"roleSort\":1,\"status\":\"0\"}],\"sex\":\"1\",\"status\":\"0\",\"userId\":1L,\"userName\":\"admin\"},\"userId\":1L,\"username\":\"admin\"}";

    @Test
    void deserializeLegacyRedisLoginUser()
    {
        FastJson2JsonRedisSerializer<Object> serializer = new FastJson2JsonRedisSerializer<>(Object.class);
        Object cached = serializer.deserialize(LEGACY_REDIS_JSON.getBytes(StandardCharsets.UTF_8));
        Assertions.assertNotNull(cached);

        LoginUser loginUser = JSON.parseObject(JSON.toJSONString(cached), LoginUser.class);
        Assertions.assertEquals("admin", loginUser.getUsername());
    }

    @Test
    void roundTripShouldNotPersistTransientRoleFields()
    {
        LoginUser loginUser = buildSampleLoginUser();
        FastJson2JsonRedisSerializer<Object> serializer = new FastJson2JsonRedisSerializer<>(Object.class);
        byte[] bytes = serializer.serialize(loginUser);
        String json = new String(bytes, StandardCharsets.UTF_8);

        Assertions.assertFalse(json.contains("\"admin\":"));
        Assertions.assertFalse(json.contains("\"flag\":"));

        Object cached = serializer.deserialize(bytes);
        Assertions.assertNotNull(cached);
    }

    private LoginUser buildSampleLoginUser()
    {
        SysRole role = new SysRole(1L);
        role.setRoleName("超级管理员");
        role.setRoleKey("admin");
        role.setRoleSort(1);
        role.setDataScope("1");
        role.setStatus("0");
        role.setFlag(true);

        SysDept dept = new SysDept();
        dept.setDeptId(103L);
        dept.setDeptName("研发部门");
        dept.setParentId(101L);
        dept.setAncestors("0,100,101");
        dept.setOrderNum(1);
        dept.setLeader("若依");
        dept.setStatus("0");

        SysUser user = new SysUser(1L);
        user.setUserName("admin");
        user.setNickName("超级管理员");
        user.setEmail("ry@163.com");
        user.setPhonenumber("15888888888");
        user.setSex("1");
        user.setStatus("0");
        user.setDelFlag("0");
        user.setDeptId(103L);
        user.setDept(dept);
        user.setRoles(java.util.Collections.singletonList(role));

        LoginUser loginUser = new LoginUser(1L, 103L, user, new java.util.HashSet<>(java.util.Collections.singleton("*:*:*")));
        loginUser.setToken("96dc6244-2273-489d-865f-36da1c8999bc");
        loginUser.setLoginTime(1780480671190L);
        loginUser.setExpireTime(1780482471190L);
        loginUser.setIpaddr("115.238.57.190");
        loginUser.setLoginLocation("XX XX");
        loginUser.setBrowser("Chrome 148");
        loginUser.setOs("Windows10");
        return loginUser;
    }
}
