"use strict";
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());
    });
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.Walker = void 0;
const error_1 = require("../error");
const message_1 = require("../message");
class Walker {
    constructor(manager) {
        this.meta = {};
        this.manager = manager;
    }
    getMetadataVersion() {
        return this.meta.version;
    }
    getMetadataProvider() {
        // TODO differentiate between multiple providers
        return "AMAZON";
    }
    load(ctx, metaRef) {
        return __awaiter(this, void 0, void 0, function* () {
            const ret = yield this.manager.get(ctx, message_1.ExtendedMessageMetadata, this.manager.bucket, metaRef);
            if (ret instanceof Error) {
                return new error_1.RetriableError(ret);
            }
            if (!ret) {
                return new Error("no metadata found");
            }
            this.meta = ret;
            return undefined;
        });
    }
    walk(ctx, schemaKey, config) {
        return __awaiter(this, void 0, void 0, function* () {
            if (!config.function && !config.parser) {
                return [null, new Error("missing walk configuration")];
            }
            const ret = new Array();
            if (config.parser) {
                config.parser.setup(ctx);
            }
            for (const entry of this.meta.getSchemaEntries(schemaKey) || []) {
                let payload = undefined;
                if (config.retriever == 'object') {
                    payload = yield this.manager.get(ctx, Object, this.manager.bucket, this.meta.getReference(entry));
                }
                else if (config.retriever == 'string') {
                    payload = yield this.manager.getRawString(ctx, this.manager.bucket, this.meta.getReference(entry));
                }
                let tag = this.meta.getTags(entry);
                if (config.injectTags) {
                    tag = Object.assign(Object.assign({}, tag), config.injectTags);
                }
                if (payload instanceof Error) {
                    return [null, payload];
                }
                if (!payload) {
                    continue;
                }
                let callRet = [null, null];
                if (config.function) {
                    callRet = config.function(ctx, this.meta.version, tag, payload);
                }
                else if (config.parser) {
                    callRet = yield config.parser.parse(ctx, tag, payload);
                }
                if (callRet[1]) {
                    return [null, callRet[1]];
                }
                ret.push(callRet[0]);
            }
            return [ret, null];
        });
    }
}
exports.Walker = Walker;
//# sourceMappingURL=meta-walker.js.map