import {
	isApiKeyScope,
	type ApiKeyScope,
	type AuthPrincipal,
	type GlobalRole,
	type Scope,
} from './types.ee';

export const OWNER_API_KEY_SCOPES: ApiKeyScope[] = [
	'user:read',
	'user:list',
	'user:create',
	'user:changeRole',
	'user:delete',
	'user:enforceMfa',
	'sourceControl:pull',
	'securityAudit:generate',
	'project:create',
	'project:update',
	'project:delete',
	'project:list',
	'variable:create',
	'variable:delete',
	'variable:list',
	'variable:update',
	'tag:create',
	'tag:read',
	'tag:update',
	'tag:delete',
	'tag:list',
	'workflowTags:update',
	'workflowTags:list',
	'executionTags:update',
	'executionTags:list',
	'workflow:create',
	'workflow:read',
	'workflow:update',
	'workflow:delete',
	'workflow:list',
	'workflow:move',
	'workflow:activate',
	'workflow:deactivate',
	'execution:delete',
	'execution:read',
	'execution:retry',
	'execution:stop',
	'execution:list',
	'credential:create',
	'credential:update',
	'credential:move',
	'credential:delete',
	'credential:list',
	'dataTable:create',
	'dataTable:read',
	'dataTable:update',
	'dataTable:delete',
	'dataTable:list',
	'dataTableRow:create',
	'dataTableRow:read',
	'dataTableRow:update',
	'dataTableRow:delete',
	'dataTableRow:upsert',
];

export const ADMIN_API_KEY_SCOPES: ApiKeyScope[] = OWNER_API_KEY_SCOPES;

export const MEMBER_API_KEY_SCOPES: ApiKeyScope[] = [
	'tag:create',
	'tag:read',
	'tag:update',
	'tag:list',
	'workflowTags:update',
	'workflowTags:list',
	'executionTags:update',
	'executionTags:list',
	'workflow:create',
	'workflow:read',
	'workflow:update',
	'workflow:delete',
	'workflow:list',
	'workflow:move',
	'workflow:activate',
	'workflow:deactivate',
	'execution:delete',
	'execution:read',
	'execution:retry',
	'execution:stop',
	'execution:list',
	'credential:create',
	'credential:update',
	'credential:move',
	'credential:delete',
	'dataTable:create',
	'dataTable:read',
	'dataTable:update',
	'dataTable:delete',
	'dataTable:list',
	'dataTableRow:create',
	'dataTableRow:read',
	'dataTableRow:update',
	'dataTableRow:delete',
	'dataTableRow:upsert',
];

export const CHAT_USER_API_KEY_SCOPES: ApiKeyScope[] = [];

/**
 * This is a bit of a mess, because we are handing out scopes in API keys that are only
 * valid for the personal project, which is enforced in the public API, because the workflows,
 * execution endpoints are limited to the personal project.
 * This is a temporary solution until we have a better way to handle personal projects and API key scopes!
 */
export const API_KEY_SCOPES_FOR_IMPLICIT_PERSONAL_PROJECT: ApiKeyScope[] = [
	'workflowTags:update',
	'workflowTags:list',
	'executionTags:update',
	'executionTags:list',
	'workflow:create',
	'workflow:read',
	'workflow:update',
	'workflow:delete',
	'workflow:list',
	'workflow:move',
	'workflow:activate',
	'workflow:deactivate',
	'execution:delete',
	'execution:read',
	'execution:retry',
	'execution:stop',
	'execution:list',
	'credential:create',
	'credential:update',
	'credential:move',
	'credential:delete',
	'dataTable:create',
	'dataTable:read',
	'dataTable:update',
	'dataTable:delete',
	'dataTable:list',
	'dataTableRow:create',
	'dataTableRow:read',
	'dataTableRow:update',
	'dataTableRow:delete',
	'dataTableRow:upsert',
];

const MAP_ROLE_SCOPES: Record<GlobalRole, ApiKeyScope[]> = {
	'global:owner': OWNER_API_KEY_SCOPES,
	'global:admin': ADMIN_API_KEY_SCOPES,
	'global:member': MEMBER_API_KEY_SCOPES,
	'global:chatUser': CHAT_USER_API_KEY_SCOPES,
};

export const getApiKeyScopesForRole = (user: AuthPrincipal) => {
	if (user.role.slug === 'global:chatUser') {
		return [];
	}

	return [
		...new Set(
			(user.role.scopes.map((scope) => scope.slug) as Array<Scope | ApiKeyScope>)
				.concat(API_KEY_SCOPES_FOR_IMPLICIT_PERSONAL_PROJECT)
				.filter(isApiKeyScope),
		),
	];
};

export const getOwnerOnlyApiKeyScopes = () => {
	const ownerScopes = new Set<ApiKeyScope>(MAP_ROLE_SCOPES['global:owner']);
	const memberScopes = new Set<ApiKeyScope>(MAP_ROLE_SCOPES['global:member']);
	memberScopes.forEach((item) => ownerScopes.delete(item));
	return Array.from(ownerScopes);
};
