// SDK Permission client. Typed status read + grant request transport
// only (Wave 2 admission rule). Wave 5 owns full grant lifecycle.
import { isCanonicalGrantState, } from './types.js';
export class PermissionClientError extends Error {
    cause;
    code;
    constructor(code, message, cause) {
        super(message);
        this.cause = cause;
        this.code = code;
        this.name = 'PermissionClientError';
    }
}
export class PermissionClient {
    transport;
    constructor(transport) {
        this.transport = transport;
        if (transport === null || transport === undefined) {
            throw new PermissionClientError('invalid-dependency', 'PermissionClient: transport is required');
        }
    }
    async getGrantStatus(grantId) {
        if (typeof grantId !== 'string' || grantId.length === 0) {
            throw new PermissionClientError('missing-required-field', 'getGrantStatus: grantId is required');
        }
        let response;
        try {
            response = await this.transport.getGrantStatus(grantId);
        }
        catch (error) {
            throw new PermissionClientError('transport-error', 'getGrantStatus transport error', error);
        }
        if (!response || !response.grant) {
            throw new PermissionClientError('missing-required-field', 'getGrantStatus response missing grant');
        }
        if (!isCanonicalGrantState(response.state)) {
            throw new PermissionClientError('non-canonical-response', `getGrantStatus state "${String(response.state)}" is not canonical`);
        }
        if (typeof response.grant.grantId !== 'string' || response.grant.grantId.length === 0) {
            throw new PermissionClientError('missing-required-field', 'getGrantStatus response.grant missing grantId');
        }
        return response;
    }
    async requestGrant(request) {
        if (!request || typeof request.appId !== 'string' || request.appId.length === 0) {
            throw new PermissionClientError('missing-required-field', 'requestGrant: appId is required');
        }
        if (typeof request.scopeKey !== 'string' || request.scopeKey.length === 0) {
            throw new PermissionClientError('missing-required-field', 'requestGrant: scopeKey is required');
        }
        if (typeof request.subjectUserId !== 'string' || request.subjectUserId.length === 0) {
            throw new PermissionClientError('missing-required-field', 'requestGrant: subjectUserId is required');
        }
        if (typeof request.reason !== 'string' || request.reason.length === 0) {
            throw new PermissionClientError('missing-required-field', 'requestGrant: reason is required');
        }
        let response;
        try {
            response = await this.transport.requestGrant(request);
        }
        catch (error) {
            throw new PermissionClientError('transport-error', 'requestGrant transport error', error);
        }
        if (!response || response.accepted !== true || typeof response.grantId !== 'string' || response.grantId.length === 0) {
            throw new PermissionClientError('missing-required-field', 'requestGrant response missing accepted or grantId');
        }
        if (response.state !== 'pending') {
            throw new PermissionClientError('non-canonical-response', `requestGrant response state must be 'pending', got "${String(response.state)}"`);
        }
        return response;
    }
}
//# sourceMappingURL=client.js.map