package com.cloudhandson.vpdbackoffice.service;

import static org.assertj.core.api.Assertions.assertThat;

import com.cloudhandson.vpdbackoffice.domain.effective.EffectiveMatrixView;
import com.cloudhandson.vpdbackoffice.domain.group.AppGroup;
import com.cloudhandson.vpdbackoffice.domain.group.GroupRoleView;
import com.cloudhandson.vpdbackoffice.domain.group.GroupUserView;
import com.cloudhandson.vpdbackoffice.domain.permission.AppRole;
import com.cloudhandson.vpdbackoffice.domain.permission.PermissionView;
import com.cloudhandson.vpdbackoffice.domain.user.AppUser;
import com.cloudhandson.vpdbackoffice.domain.user.UserRoleView;
import java.util.List;
import org.junit.jupiter.api.Test;

class EffectiveMatrixServiceTest {

  @Test
  void combinesDirectAndGroupInheritedRoles() {
    EffectiveMatrixService service = new EffectiveMatrixService(
        new UserService(null, null) {
          @Override
          public List<AppUser> findAll() {
            return List.of(new AppUser(1L, "agent_ops", "E100", "OPS", "N", "Y"));
          }

          @Override
          public List<UserRoleView> findUserRoles() {
            return List.of(new UserRoleView(1L, "agent_ops", 10L, "DIRECT_ROLE"));
          }
        },
        new GroupService(null, null) {
          @Override
          public List<AppGroup> findAll() {
            return List.of(new AppGroup(100L, "OPS_GROUP", "운영그룹", null, "Y"));
          }

          @Override
          public List<GroupUserView> findGroupUsers() {
            return List.of(new GroupUserView(100L, "OPS_GROUP", "운영그룹", 1L, "agent_ops"));
          }

          @Override
          public List<GroupRoleView> findGroupRoles() {
            return List.of(new GroupRoleView(100L, "OPS_GROUP", "운영그룹", 20L, "GROUP_ROLE"));
          }
        },
        new PermissionService(null, null, null) {
          @Override
          public List<AppRole> findRoles() {
            return List.of(
                new AppRole(10L, "DIRECT_ROLE", null, "PUBLIC"),
                new AppRole(20L, "GROUP_ROLE", null, "INTERNAL")
            );
          }

          @Override
          public List<PermissionView> findPermissionViews() {
            return List.of(
                new PermissionView(1000L, 10L, "DIRECT_ROLE", 1L, "BOARD_POSTS", "SELECT", "ALLOW", "ALL", null, "ALL ROWS", "컬럼 원문/마스킹은 컬럼 마스킹에서 관리"),
                new PermissionView(1001L, 20L, "GROUP_ROLE", 2L, "BOARD_ASSIGNMENTS", "SELECT", "ALLOW", "ALL", null, "ALL ROWS", "컬럼 원문/마스킹은 컬럼 마스킹에서 관리")
            );
          }
        }
    );

    EffectiveMatrixView matrix = service.matrix();

    assertThat(matrix.users()).hasSize(1);
    assertThat(matrix.users().getFirst().directRoles()).containsExactly("DIRECT_ROLE");
    assertThat(matrix.users().getFirst().inheritedRoles()).containsExactly("GROUP_ROLE");
    assertThat(matrix.users().getFirst().effectiveRoles()).containsExactly("DIRECT_ROLE", "GROUP_ROLE");
    assertThat(matrix.users().getFirst().permissionCount()).isEqualTo(2);
    assertThat(matrix.groups().getFirst().users()).containsExactly("agent_ops");
    assertThat(matrix.groups().getFirst().roles()).containsExactly("GROUP_ROLE");
    assertThat(matrix.roles().get(1).affectedUsers()).containsExactly("agent_ops");
  }
}
