import { authenticate } from '../core/auth.js';
import { DwnErrorCode } from '../core/dwn-error.js';
import { messageReplyFromError } from '../core/message-reply.js';
import { ProtocolsQuery } from '../interfaces/protocols-query.js';
import { removeUndefinedProperties } from '@enbox/common';
import { DwnInterfaceName, DwnMethodName } from '../enums/dwn-interface-method.js';
export class ProtocolsQueryHandler {
    deps;
    constructor(deps) {
        this.deps = deps;
    }
    async handle({ tenant, message }) {
        let protocolsQuery;
        try {
            protocolsQuery = await ProtocolsQuery.parse(message);
        }
        catch (e) {
            return messageReplyFromError(e, 400);
        }
        // authentication & authorization
        try {
            await authenticate(message.authorization, this.deps.didResolver);
            await protocolsQuery.authorize(tenant, this.deps.validationStateReader);
        }
        catch (error) {
            // return public ProtocolsConfigures if query fails with a certain authentication or authorization code
            if (error.code === DwnErrorCode.AuthenticateJwsMissing || // unauthenticated
                error.code === DwnErrorCode.ProtocolsQueryUnauthorized ||
                error.code === DwnErrorCode.ProtocolsGrantAuthorizationQueryProtocolScopeMismatch) {
                const entries = await this.fetchPublishedProtocolsConfigure(tenant, protocolsQuery);
                return {
                    status: { code: 200, detail: 'OK' },
                    entries
                };
            }
            else {
                return messageReplyFromError(error, 401);
            }
        }
        const query = {
            ...message.descriptor.filter,
            interface: DwnInterfaceName.Protocols,
            method: DwnMethodName.Configure,
            isLatestBaseState: true,
        };
        removeUndefinedProperties(query);
        const { messages } = await this.deps.messageStore.query(tenant, [query]);
        return {
            status: { code: 200, detail: 'OK' },
            entries: messages
        };
    }
    ;
    /**
     * Fetches only published `ProtocolsConfigure`.
     */
    async fetchPublishedProtocolsConfigure(tenant, protocolsQuery) {
        // fetch all published `ProtocolConfigure` matching the query
        const filter = {
            ...protocolsQuery.message.descriptor.filter,
            interface: DwnInterfaceName.Protocols,
            method: DwnMethodName.Configure,
            published: true,
            isLatestBaseState: true,
        };
        const { messages: publishedProtocolsConfigure } = await this.deps.messageStore.query(tenant, [filter]);
        return publishedProtocolsConfigure;
    }
}
//# sourceMappingURL=protocols-query.js.map