import { isObject } from 'lodash';
import { map, tap } from 'rxjs/operators';
import { hasSortKey, metadataForClass } from '../../../decorator/metadata';
import { createLogger } from '../../../logger/logger';
import { fromDb, toDbOne } from '../../../mapper';
// TODO add support for indexes
var BatchGetSingleTableRequest = /** @class */ (function () {
    // todo: make use of toKey<T>(item: T, modelConstructor: ModelConstructor<T>)
    function BatchGetSingleTableRequest(dynamoRx, modelClazz, tableName, keys) {
        this.logger = 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 = metadataForClass(this.modelClazz);
        this.addKeyParams(keys);
    }
    BatchGetSingleTableRequest.prototype.execFullResponse = function () {
        var _this = this;
        this.logger.debug('request', this.params);
        return this.dynamoRx.batchGetItems(this.params).pipe(tap(function (response) { return _this.logger.debug('response', response); }), map(function (response) {
            var items;
            if (response.Responses && Object.keys(response.Responses).length && response.Responses[_this.tableName]) {
                var mapped = response.Responses[_this.tableName].map(function (attributeMap) {
                    return fromDb(attributeMap, _this.modelClazz);
                });
                items = mapped;
            }
            else {
                items = [];
            }
            return {
                Items: items,
                UnprocessedKeys: response.UnprocessedKeys,
                ConsumedCapacity: response.ConsumedCapacity,
            };
        }), tap(function (response) { return _this.logger.debug('mapped items', response.Items); }));
    };
    BatchGetSingleTableRequest.prototype.exec = function () {
        var _this = this;
        this.logger.debug('request', this.params);
        return this.dynamoRx.batchGetItems(this.params).pipe(tap(function (response) { return _this.logger.debug('response', response); }), map(function (response) {
            if (response.Responses && Object.keys(response.Responses).length && response.Responses[_this.tableName]) {
                return response.Responses[_this.tableName].map(function (attributeMap) {
                    return fromDb(attributeMap, _this.modelClazz);
                });
            }
            else {
                return [];
            }
        }), tap(function (items) { return _this.logger.debug('mapped items', items); }));
    };
    BatchGetSingleTableRequest.prototype.addKeyParams = function (keys) {
        var _this = this;
        var attributeMaps = [];
        keys.forEach(function (key) {
            var idOb = {};
            if (isObject(key)) {
                // TODO add some more checks
                // got a composite primary key
                // partition key
                var mappedPartitionKey = 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 && hasSortKey(_this.metadata)) {
                    var mappedSortKey = 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
                var value = 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,
        };
    };
    return BatchGetSingleTableRequest;
}());
export { BatchGetSingleTableRequest };
//# sourceMappingURL=batch-get-single-table.request.js.map