import { SCOPES } from '../config.js'

/** Magento admin username (lower-case) or `*` → scopes that user may be granted. */
export type UserScopes = Map<string, string[]>

const KNOWN = new Set<string>(Object.values(SCOPES))

/**
 * Parse `MCP_USER_SCOPES`, e.g.
 *   `alice=catalog:read orders:read orders:pii;*=catalog:read orders:read`
 * `*` applies to any Magento admin not listed. Omit `*` to allow only listed users.
 */
export function parseUserScopes(spec: string): UserScopes {
  const map: UserScopes = new Map()
  for (const entry of spec.split(';').map(s => s.trim()).filter(Boolean)) {
    const [user, scopeList] = entry.split('=')
    if (!user || scopeList === undefined) throw new Error(`MCP_USER_SCOPES entry "${entry}" must look like user=scope scope`)
    const scopes = scopeList.split(/\s+/).filter(Boolean)
    const unknown = scopes.filter(s => !KNOWN.has(s))
    if (unknown.length) throw new Error(`MCP_USER_SCOPES: unknown scope(s) ${unknown.join(', ')} for "${user}"`)
    if (scopes.includes(SCOPES.ORDERS_PII) && !scopes.includes(SCOPES.ORDERS_READ)) {
      throw new Error(`MCP_USER_SCOPES: "${user}" has orders:pii without orders:read`)
    }
    map.set(user.trim().toLowerCase(), scopes)
  }
  return map
}

/** Scopes to grant: what the user is allowed, narrowed to what the client asked for (if it asked). */
export function grantedScopes(config: UserScopes, username: string, requested: string[]): string[] {
  const allowed = config.get(username.toLowerCase()) ?? config.get('*') ?? []
  return requested.length ? allowed.filter(s => requested.includes(s)) : allowed
}
