package cn.reghao.autodop.dmaster.rbac.db.query;

import cn.reghao.autodop.dmaster.rbac.db.repository.RoleRepository;
import cn.reghao.autodop.dmaster.rbac.db.repository.UserRepository;
import cn.reghao.autodop.dmaster.rbac.model.po.Role;
import cn.reghao.autodop.dmaster.rbac.model.po.User;
import cn.reghao.autodop.dmaster.rbac.model.po.UserAuthority;
import cn.reghao.autodop.dmaster.rbac.model.vo.RoleVO;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Service;

import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.SetJoin;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @author reghao
 * @date 2021-07-12 15:32:26
 */
@Service
public class RoleQueryImpl implements RoleQuery {
    private final RoleRepository roleRepository;
    private final UserRepository userRepository;

    public RoleQueryImpl(RoleRepository roleRepository, UserRepository userRepository) {
        this.roleRepository = roleRepository;
        this.userRepository = userRepository;
    }

    @Override
    public List<Role> findAll() {
        return roleRepository.findAll();
    }

    @Override
    public Role findById(int id) {
        return roleRepository.findById(id).orElse(null);
    }

    @Override
    public Role findByTitle(String title) {
        return roleRepository.findByTitle(title);
    }

    @Override
    public Page<RoleVO> getRoleVOByPage(PageRequest pageRequest) {
        return roleRepository.findAll(pageRequest).map(RoleVO::new);
    }

    @Override
    public List<RoleVO> getByMatchName(String name) {
        Specification<Role> specification = (root, query, cb) -> {
            String likeQuery = String.format("%%%s%%", name);
            Predicate predicate = cb.like(root.get("name"), likeQuery);
            return cb.and(predicate);
        };
        return roleRepository.findAll(specification).stream().map(RoleVO::new).collect(Collectors.toList());
    }

    @Override
    public RoleVO getRoleVOById(Integer id) {
        Role role = findById(id);
        return role != null ? new RoleVO(role) : null;
    }

    /**
     * 获取拥有角色的用户
     *
     * @param
     * @return
     * @date 2021-07-14 下午2:57
     */
    @Override
    public List<User> getUsersByRoleId(Integer id) {
        Role role = findById(id);
        return getUsersByRole(role);
    }

    @Override
    public List<User> getUsersByRole(Role role) {
        String title = role.getTitle();
        Specification<User> specification = ((root, query, cb) -> {
            SetJoin<User, UserAuthority> setJoin = root.joinSet("authorities");
            Predicate predicate = cb.equal(setJoin.get("role"), title);
            return cb.and(predicate);
        });
        return userRepository.findAll(specification);
    }
}
