import * as tslib_1 from "tslib";
import { isObject, isString } from 'lodash';
import { map } from 'rxjs/operators';
import { hasSortKey } from '../../decorator/metadata';
import { metadataForClass } from '../../decorator/metadata/metadata-helper';
import { fromDb, toDbOne } from '../../mapper';
import { DEFAULT_SESSION_VALIDITY_ENSURER } from '../default-session-validity-ensurer.const';
import { DEFAULT_TABLE_NAME_RESOLVER } from '../default-table-name-resolver.const';
import { DynamoRx } from '../dynamo-rx';
import { REGEX_TABLE_NAME } from '../request/regex';
var BatchGetRequest = /** @class */ (function () {
    function BatchGetRequest(tableNameResolver, sessionValidityEnsurer) {
        if (tableNameResolver === void 0) { tableNameResolver = DEFAULT_TABLE_NAME_RESOLVER; }
        if (sessionValidityEnsurer === void 0) { sessionValidityEnsurer = DEFAULT_SESSION_VALIDITY_ENSURER; }
        this.tableNameResolver = tableNameResolver;
        this.tables = new Map();
        this.dynamoRx = new DynamoRx(sessionValidityEnsurer);
        this.params = {
            RequestItems: {},
        };
    }
    /**
     * @param {ModelConstructor<T>} modelClazz
     * @param {any[]} keys either a simple string for partition key or an object with partitionKey and sortKey
     * @returns {BatchGetSingleTableRequest}
     */
    BatchGetRequest.prototype.forModel = function (modelClazz, keys) {
        var tableName = this.getTableName(modelClazz, this.tableNameResolver);
        if (this.tables.has(tableName)) {
            throw new Error('table name already exists, please provide all the keys for the same table at once');
        }
        this.tables.set(tableName, modelClazz);
        var metadata = metadataForClass(modelClazz);
        var attributeMaps = [];
        // loop over all the keys
        keys.forEach(function (key) {
            var idOb = {};
            if (isString(key)) {
                // got a simple primary key
                var value = toDbOne(key);
                if (value === null) {
                    throw Error('please provide an actual value for partition key');
                }
                idOb[metadata.getPartitionKey()] = value;
            }
            else if (isObject(key) && key.partitionKey !== undefined && key.partitionKey !== null) {
                // 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[metadata.getPartitionKey()] = mappedPartitionKey;
                // sort key
                var mappedSortKey = toDbOne(key.sortKey);
                if (mappedSortKey === null) {
                    throw Error('please provide an actual value for partition key');
                }
                if (hasSortKey(metadata)) {
                    idOb[metadata.getSortKey()] = mappedSortKey;
                }
            }
            else {
                throw new Error('a key must either be a string or a PrimaryKey');
            }
            attributeMaps.push(idOb);
        });
        this.params.RequestItems[tableName] = {
            Keys: attributeMaps,
        };
        return this;
    };
    BatchGetRequest.prototype.execFullResponse = function () {
        var _this = this;
        return this.dynamoRx.batchGetItems(this.params).pipe(map(function (response) {
            var Responses = {};
            if (response.Responses && Object.keys(response.Responses).length) {
                Responses = Object.entries(response.Responses).reduce(function (u, _a) {
                    var _b = tslib_1.__read(_a, 2), key = _b[0], val = _b[1];
                    u[key] = val.map(function (attributes) { return fromDb(attributes, _this.tables.get(key)); });
                    return u;
                }, {});
            }
            return {
                ConsumedCapacity: response.ConsumedCapacity,
                UnprocessedKeys: response.UnprocessedKeys,
                Responses: Responses,
            };
        }));
    };
    BatchGetRequest.prototype.exec = function () {
        var _this = this;
        return this.dynamoRx.batchGetItems(this.params).pipe(map(function (response) {
            if (response.Responses && Object.keys(response.Responses).length) {
                return Object.entries(response.Responses).reduce(function (u, _a) {
                    var _b = tslib_1.__read(_a, 2), key = _b[0], val = _b[1];
                    u[key] = val.map(function (attributeMap) { return fromDb(attributeMap, _this.tables.get(key)); });
                    return u;
                }, {});
            }
            return {};
        }));
    };
    BatchGetRequest.prototype.getTableName = function (modelClazz, tableNameResolver) {
        var tableName = tableNameResolver(metadataForClass(modelClazz).modelOptions.tableName);
        if (!REGEX_TABLE_NAME.test(tableName)) {
            throw new Error('make sure the table name only contains these characters «a-z A-Z 0-9 - _ .» and is between 3 and 255 characters long');
        }
        return tableName;
    };
    return BatchGetRequest;
}());
export { BatchGetRequest };
//# sourceMappingURL=batch-get.request.js.map