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',
	'sourceControl:pull',
	'gitConnection:create',
	'gitConnection:read',
	'gitConnection:update',
	'gitConnection:delete',
	'gitConnection:list',
	'gitConnection:clone',
	'gitConnection:push',
	'gitConnection:manageProjects',
	'gitConnection:pull',
	'securityAudit:generate',
	'securitySettings:manage',
	'saml:manage',
	'oidc:manage',
	'otel:manage',
	'ldap:manage',
	'ldap:sync',
	'eventBusDestination:list',
	'eventBusDestination:read',
	'eventBusDestination:create',
	'eventBusDestination:update',
	'eventBusDestination:test',
	'eventBusDestination:delete',
	'project:create',
	'project:update',
	'project:delete',
	'project:list',
	'project:export',
	'project:manageMembers',
	'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:export',
	'workflow:import',
	'workflow:list',
	'workflow:move',
	'workflow:activate',
	'workflow:deactivate',
	'execution:delete',
	'execution:read',
	'execution:retry',
	'execution:stop',
	'execution:list',
	'testRun:read',
	'testRun:list',
	'testRun:create',
	'testRun:cancel',
	'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',
	'folder:create',
	'folder:delete',
	'folder:read',
	'folder:update',
	'folder:list',
	'dataTableColumn:create',
	'dataTableColumn:read',
	'dataTableColumn:update',
	'dataTableColumn:delete',
	'insights:read',
	'role:manage',
	'role:list',
	'role:read',
	'roleMappingRule:create',
	'roleMappingRule:delete',
	'roleMappingRule:list',
	'roleMappingRule:update',
];

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:export',
	'workflow:import',
	'workflow:list',
	'workflow:move',
	'workflow:activate',
	'workflow:deactivate',
	'project:export',
	'execution:delete',
	'execution:read',
	'execution:retry',
	'execution:stop',
	'execution:list',
	'testRun:read',
	'testRun:list',
	'testRun:create',
	'testRun:cancel',
	'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',
	'folder:create',
	'folder:delete',
	'folder:read',
	'folder:update',
	'folder:list',
	'dataTableColumn:create',
	'dataTableColumn:read',
	'dataTableColumn:update',
	'dataTableColumn:delete',
];

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:export',
	'workflow:import',
	'workflow:list',
	'workflow:move',
	'workflow:activate',
	'workflow:deactivate',
	'project:export',
	'execution:delete',
	'execution:read',
	'execution:retry',
	'execution:stop',
	'execution:list',
	'testRun:read',
	'testRun:list',
	'testRun:create',
	'testRun:cancel',
	'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',
	'dataTableColumn:create',
	'dataTableColumn:read',
	'dataTableColumn:update',
	'dataTableColumn:delete',
];

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);
};
