package cn.skcks.matrix.v2.services.casbin;

import cn.skcks.matrix.v2.model.route.dto.RouteInfo;
import cn.skcks.matrix.v2.services.role.RoleService;
import org.casbin.jcasbin.main.Enforcer;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.HashSet;
import java.util.List;
import java.util.concurrent.ForkJoinPool;

public interface CasbinRegister {
    void register(Enforcer enforcer, List<RouteInfo> routes, RoleService roleService);

    Logger log = LoggerFactory.getLogger(CasbinRegister.class);

    static void addPolicies(Enforcer enforcer, String role, String system, List<RouteInfo> routes) {
        HashSet<List<String>> params = new HashSet<>(routes.size());
        for (RouteInfo route : routes) {
            Permission permission = new Permission(Permission.Identify.ROLE, role, system, route.requestUrl, route.requestMethod);
            params.add(permission.getPolicyParamList());
        }

        List<List<String>> existPolicies = enforcer.getFilteredPolicy(0, role, system);

        existPolicies = existPolicies.stream().toList();
        existPolicies.forEach(existPolicy -> {
            if (!params.contains(existPolicy)) {
                log.info("[casbin] {} 移除无效规则 {}", role, existPolicy);
                enforcer.removePolicy(existPolicy);
            }
        });

        // 批量添加规则 enforcer.addPolicies 在部分权限缺失时存在 bug 依然会遗漏缺失的规则 故改为并行单条插入
        ForkJoinPool pool = new ForkJoinPool(Runtime.getRuntime().availableProcessors() * 2);
        pool.submit(()-> params.stream().toList().parallelStream().forEach(enforcer::addPolicy));
    }
}
