package com.ffii.fpsms.modules.user.service;

import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.ffii.core.support.AbstractService;
import com.ffii.core.support.JdbcDao;
import com.ffii.fpsms.modules.user.entity.User;

@Service
public class UserAuthorityService extends AbstractService {
  private static final String USER_AUTH_SQL = "SELECT a.authority"
      + " FROM `user` u"
      + " JOIN user_authority ua ON ua.userId = u.id"
      + " JOIN authority a ON a.id = ua.authId"
      + " WHERE u.deleted = 0"
      + " AND u.id = :userId";
  private static final String UNION_SQL = " UNION ";
  private static final String GROUP_AUTH_SQL = "SELECT a.authority"
      + " FROM `user` u"
      + " JOIN user_group ug ON ug.userId = u.id"
      + " JOIN `group` g ON g.deleted = 0 AND g.id = ug.groupId"
      + " JOIN group_authority ga ON ga.groupId = g.id"
      + " JOIN authority a ON a.id = ga.authId"
      + " WHERE u.deleted = 0"
      + " AND u.id = :userId";

  public UserAuthorityService(JdbcDao jdbcDao) {
    super(jdbcDao);
  }

  @Transactional(rollbackFor = Exception.class)
  public Set<SimpleGrantedAuthority> getUserAuthority(User user) {
    Set<SimpleGrantedAuthority> auths = new HashSet<>();
    List<Map<String, Object>> records = jdbcDao.queryForList(USER_AUTH_SQL + UNION_SQL + GROUP_AUTH_SQL,
        Map.of("userId", user.getId()));

    records.forEach(item -> auths.add(new SimpleGrantedAuthority((String) item.get("authority"))));
    return auths;
  }

}
