import * as access from '../../services/access-control.js';
import { AccessDeniedError, sendAccessDenied, } from '../../services/workspace-access.js';
/** Convert an AuthUser from the request to a GitUser for commit attribution. */
export function reqGitUser(req) {
    const user = req.user;
    if (!user)
        return undefined;
    // Use handle (a stable, human-readable, email-free slug) as the identity
    // for created_by / updated_by frontmatter and as the git author. Real
    // emails would land in committed entity content + git history, where
    // they're hard to scrub later.
    return { id: user.handle, name: user.displayName, email: `${user.handle}@studiograph.local` };
}
export function reqUser(req) {
    return req.user;
}
/** Parse the `include_private` query param or `X-Studiograph-Include-Private`
 *  header into an access option. The flag is owner-gated by the access
 *  helpers themselves — non-owners passing it have no effect. */
function reqAccessOptions(req) {
    const query = req.query ?? {};
    const headers = req.headers ?? {};
    const flagged = query.include_private === '1' ||
        query.include_private === 'true' ||
        headers['x-studiograph-include-private'] === '1' ||
        headers['x-studiograph-include-private'] === 'true';
    return flagged ? { includePrivate: true } : {};
}
export function getAccessibleRepos(req, workspaceManager, authService) {
    return access.getAccessibleRepos(reqUser(req), workspaceManager, authService, reqAccessOptions(req));
}
/** Accessible repos MINUS `system` folders (the reserved asset store). Use for
 *  knowledge/content surfaces (entity summaries, graph topology, search,
 *  graph-health) so the asset store's wrapper entities don't pollute them. The
 *  asset manager + authz still use getAccessibleRepos (system included). */
export function getContentRepos(req, workspaceManager, authService) {
    return getAccessibleRepos(req, workspaceManager, authService).filter(r => !r.system);
}
export function hasRepoAccess(req, repoName, workspaceManager, authService) {
    return access.hasRepoAccess(reqUser(req), repoName, workspaceManager, authService, reqAccessOptions(req));
}
export function canWriteRepo(req, repoName, workspaceManager, authService) {
    return access.canWriteRepo(reqUser(req), repoName, workspaceManager, authService);
}
export function isFolderAdminOrOwner(req, repoName, workspaceManager, authService) {
    return access.isFolderAdminOrOwner(reqUser(req), repoName, workspaceManager, authService);
}
export function getAccessibleEntityIds(req, workspaceManager, authService) {
    return access.getAccessibleEntityIds(reqUser(req), workspaceManager, authService);
}
export function filterWikilinks(wikilinks, accessibleIds) {
    return access.filterWikilinks(wikilinks, accessibleIds);
}
/**
 * Guard against non-admin members creating eager skills in shared folders:
 * eager skills inline into prompts for everyone with folder access.
 */
export function checkEagerSkillPermission(req, entityType, data, repoName, workspaceManager, authService) {
    if (entityType !== 'skill')
        return null;
    if (!data || data.loading !== 'eager')
        return null;
    const user = reqUser(req);
    if (!user)
        return null; // API key / open mode
    const personalRepo = workspaceManager.getUserPersonalRepo(user.id);
    if (personalRepo && personalRepo.name === repoName)
        return null;
    if (isFolderAdminOrOwner(req, repoName, workspaceManager, authService))
        return null;
    return 'Creating an eager skill in a shared folder requires folder admin or workspace owner. Save this skill to your personal folder or set loading to "on-demand".';
}
export function graphForRead(accessService, req, reply, repoName) {
    try {
        return accessService.graphForRead(reqUser(req), repoName);
    }
    catch (err) {
        if (err instanceof AccessDeniedError) {
            sendAccessDenied(reply, err);
            return null;
        }
        reply.status(404).send({ error: err.message });
        return null;
    }
}
export function graphForWrite(accessService, req, reply, repoName) {
    try {
        return accessService.graphForWrite(reqUser(req), repoName);
    }
    catch (err) {
        if (err instanceof AccessDeniedError) {
            sendAccessDenied(reply, err);
            return null;
        }
        reply.status(404).send({ error: err.message });
        return null;
    }
}
export function graphForAdmin(accessService, req, reply, repoName) {
    try {
        return accessService.graphForAdmin(reqUser(req), repoName);
    }
    catch (err) {
        if (err instanceof AccessDeniedError) {
            sendAccessDenied(reply, err);
            return null;
        }
        reply.status(404).send({ error: err.message });
        return null;
    }
}
//# sourceMappingURL=graph-api-access.js.map