// src/server/shared/lib/rbac.ts
// Shared RBAC helper utilities for dynamic permission lookups with in-memory cache

import { db } from '@serverShared/db/client';
import { rolePermissionsTable } from '@serverShared/db/schema';
import { and, eq } from 'drizzle-orm';

interface RolesCacheEntry {
  roles: string[];
  timestamp: number;
}

const rolesByPermissionCache: Record<string, RolesCacheEntry> = {};
const ROLES_CACHE_TTL_MS = 60 * 1000;

/**
 * Возвращает список ролей, у которых включено указанное permission.
 * Формат permission: "resource:action".
 */
export async function getRolesWithPermission(permission: string): Promise<string[]> {
  const now = Date.now();
  const cached = rolesByPermissionCache[permission];

  if (cached && now - cached.timestamp <= ROLES_CACHE_TTL_MS) {
    return cached.roles;
  }

  const [resource, action] = permission.split(':');
  if (!resource || !action) {
    return [];
  }

  const rows = await db
    .selectDistinct({ role: rolePermissionsTable.role })
    .from(rolePermissionsTable)
    .where(
      and(
        eq(rolePermissionsTable.resource, resource),
        eq(rolePermissionsTable.action, action),
        eq(rolePermissionsTable.isEnabled, true),
      ),
    );

  const roles = rows.map((row) => row.role);
  rolesByPermissionCache[permission] = {
    roles,
    timestamp: now,
  };

  return roles;
}

/**
 * Сбрасывает кэш ролей по permission.
 * Если permission не передан — очищает весь кэш.
 */
export function clearRolesWithPermissionCache(permission?: string): void {
  if (permission) {
    delete rolesByPermissionCache[permission];
    return;
  }

  for (const key of Object.keys(rolesByPermissionCache)) {
    delete rolesByPermissionCache[key];
  }
}

