var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
    return new (P || (P = Promise))(function (resolve, reject) {
        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
        function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
        function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
};
import { DataStream } from '../utils/data-stream.js';
import { DwnConstant } from '../core/dwn-constant.js';
import { Encoder } from '../utils/encoder.js';
import { messageReplyFromError } from '../core/message-reply.js';
import { MessagesGet } from '../interfaces/messages-get.js';
import { authenticate, authorize } from '../core/auth.js';
import { DwnInterfaceName, DwnMethodName, Message } from '../core/message.js';
export class MessagesGetHandler {
    constructor(didResolver, messageStore, dataStore) {
        this.didResolver = didResolver;
        this.messageStore = messageStore;
        this.dataStore = dataStore;
    }
    handle({ tenant, message }) {
        return __awaiter(this, void 0, void 0, function* () {
            let messagesGet;
            try {
                messagesGet = yield MessagesGet.parse(message);
            }
            catch (e) {
                return messageReplyFromError(e, 400);
            }
            try {
                yield authenticate(message.authorization, this.didResolver);
                yield authorize(tenant, messagesGet);
            }
            catch (e) {
                return messageReplyFromError(e, 401);
            }
            const promises = [];
            const messageCids = new Set(message.descriptor.messageCids);
            for (const messageCid of messageCids) {
                const promise = this.messageStore.get(tenant, messageCid)
                    .then(message => {
                    return { messageCid, message };
                })
                    .catch(_ => {
                    return { messageCid, message: undefined, error: `Failed to get message ${messageCid}` };
                });
                promises.push(promise);
            }
            const messages = yield Promise.all(promises);
            // for every message, include associated data as `encodedData` IF:
            //  * its a RecordsWrite
            //  * the data size is equal or smaller than the size threshold
            //! NOTE: this is somewhat duplicate code that also exists in `StorageController.query`.
            for (const entry of messages) {
                const { message } = entry;
                if (!message) {
                    continue;
                }
                const { interface: messageInterface, method } = message.descriptor;
                if (messageInterface !== DwnInterfaceName.Records || method !== DwnMethodName.Write) {
                    continue;
                }
                const dataCid = message.descriptor.dataCid;
                const dataSize = message.descriptor.dataSize;
                if (dataCid !== undefined && dataSize <= DwnConstant.maxDataSizeAllowedToBeEncoded) {
                    const messageCid = yield Message.getCid(message);
                    const result = yield this.dataStore.get(tenant, messageCid, dataCid);
                    if (result) {
                        const dataBytes = yield DataStream.toBytes(result.dataStream);
                        entry.encodedData = Encoder.bytesToBase64Url(dataBytes);
                    }
                }
            }
            return {
                status: { code: 200, detail: 'OK' },
                messages
            };
        });
    }
}
//# sourceMappingURL=messages-get.js.map