"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const lodash_1 = require("lodash");
const operators_1 = require("rxjs/operators");
const metadata_1 = require("../../../decorator/metadata");
const logger_1 = require("../../../logger/logger");
const mapper_1 = require("../../../mapper");
// TODO add support for indexes
class BatchGetSingleTableRequest {
    // todo: make use of toKey<T>(item: T, modelConstructor: ModelConstructor<T>)
    constructor(dynamoRx, modelClazz, tableName, keys) {
        this.logger = logger_1.createLogger('dynamo.request.BatchGetSingleTableRequest', modelClazz);
        this.dynamoRx = dynamoRx;
        if (modelClazz === null || modelClazz === undefined) {
            throw new Error("please provide the model clazz for the request, won't work otherwise");
        }
        this.modelClazz = modelClazz;
        this.params = {
            RequestItems: {},
        };
        this.tableName = tableName;
        this.metadata = metadata_1.metadataForClass(this.modelClazz);
        this.addKeyParams(keys);
    }
    execFullResponse() {
        this.logger.debug('request', this.params);
        return this.dynamoRx.batchGetItems(this.params).pipe(operators_1.tap(response => this.logger.debug('response', response)), operators_1.map(response => {
            let items;
            if (response.Responses && Object.keys(response.Responses).length && response.Responses[this.tableName]) {
                const mapped = response.Responses[this.tableName].map(attributeMap => mapper_1.fromDb(attributeMap, this.modelClazz));
                items = mapped;
            }
            else {
                items = [];
            }
            return {
                Items: items,
                UnprocessedKeys: response.UnprocessedKeys,
                ConsumedCapacity: response.ConsumedCapacity,
            };
        }), operators_1.tap(response => this.logger.debug('mapped items', response.Items)));
    }
    exec() {
        this.logger.debug('request', this.params);
        return this.dynamoRx.batchGetItems(this.params).pipe(operators_1.tap(response => this.logger.debug('response', response)), operators_1.map(response => {
            if (response.Responses && Object.keys(response.Responses).length && response.Responses[this.tableName]) {
                return response.Responses[this.tableName].map(attributeMap => mapper_1.fromDb(attributeMap, this.modelClazz));
            }
            else {
                return [];
            }
        }), operators_1.tap(items => this.logger.debug('mapped items', items)));
    }
    addKeyParams(keys) {
        const attributeMaps = [];
        keys.forEach(key => {
            const idOb = {};
            if (lodash_1.isObject(key)) {
                // TODO add some more checks
                // got a composite primary key
                // partition key
                const mappedPartitionKey = mapper_1.toDbOne(key.partitionKey);
                if (mappedPartitionKey === null) {
                    throw Error('please provide an actual value for partition key');
                }
                idOb[this.metadata.getPartitionKey()] = mappedPartitionKey;
                // sort key
                if (key.sortKey && metadata_1.hasSortKey(this.metadata)) {
                    const mappedSortKey = mapper_1.toDbOne(key.sortKey);
                    if (mappedSortKey === null) {
                        throw Error('please provide an actual value for sort key');
                    }
                    idOb[this.metadata.getSortKey()] = mappedSortKey;
                }
            }
            else {
                // got a simple primary key
                const value = mapper_1.toDbOne(key);
                if (value === null) {
                    throw Error('please provide an actual value for partition key');
                }
                idOb[this.metadata.getPartitionKey()] = value;
            }
            attributeMaps.push(idOb);
        });
        this.params.RequestItems[this.tableName] = {
            Keys: attributeMaps,
        };
    }
}
exports.BatchGetSingleTableRequest = BatchGetSingleTableRequest;
//# sourceMappingURL=batch-get-single-table.request.js.map