import { map, tap } from 'rxjs/operators';
import { metadataForClass } from '../../../decorator/metadata';
import { randomExponentialBackoffTimer } from '../../../helper';
import { createLogger } from '../../../logger/logger';
import { createToKeyFn, fromDb } from '../../../mapper';
import { batchGetItemsFetchAll } from '../../batchget/batch-get-utils';
import { getTableName } from '../../get-table-name.function';
const MAX_REQUEST_ITEM_COUNT = 100;
const DEFAULT_TIME_SLOT = 1000;
// TODO add support for indexes
export class BatchGetSingleTableRequest {
    constructor(dynamoRx, modelClazz, keys) {
        this.mapResponse = (response) => {
            let items = [];
            if (response.Responses && Object.keys(response.Responses).length && response.Responses[this.tableName]) {
                const mapped = response.Responses[this.tableName].map(attributeMap => fromDb(attributeMap, this.modelClazz));
                items = mapped;
            }
            return {
                Items: items,
                UnprocessedKeys: response.UnprocessedKeys,
                ConsumedCapacity: response.ConsumedCapacity,
            };
        };
        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.metadata = metadataForClass(this.modelClazz);
        if (!this.metadata.modelOptions) {
            throw new Error('given ModelConstructor has no @Model decorator');
        }
        this.tableName = getTableName(this.metadata);
        if (keys.length > MAX_REQUEST_ITEM_COUNT) {
            throw new Error(`you can request at max ${MAX_REQUEST_ITEM_COUNT} items per request`);
        }
        this.params = {
            RequestItems: {
                [this.tableName]: {
                    Keys: keys.map(createToKeyFn(modelClazz)),
                },
            },
        };
    }
    consistentRead(value = true) {
        this.params.RequestItems[this.tableName].ConsistentRead = value;
        return this;
    }
    execNoMap(backoffTimer = randomExponentialBackoffTimer, throttleTimeSlot = DEFAULT_TIME_SLOT) {
        return this.fetch(backoffTimer, throttleTimeSlot);
    }
    execFullResponse(backoffTimer = randomExponentialBackoffTimer, throttleTimeSlot = DEFAULT_TIME_SLOT) {
        return this.fetch(backoffTimer, throttleTimeSlot).pipe(map(this.mapResponse), tap(response => this.logger.debug('mapped items', response.Items)));
    }
    exec(backoffTimer = randomExponentialBackoffTimer, throttleTimeSlot = DEFAULT_TIME_SLOT) {
        return this.fetch(backoffTimer, throttleTimeSlot).pipe(map(this.mapResponse), map(r => r.Items), tap(items => this.logger.debug('mapped items', items)));
    }
    fetch(backoffTimer = randomExponentialBackoffTimer, throttleTimeSlot = DEFAULT_TIME_SLOT) {
        this.logger.debug('request', this.params);
        return batchGetItemsFetchAll(this.dynamoRx, Object.assign({}, this.params), backoffTimer(), throttleTimeSlot)
            .pipe(tap(response => this.logger.debug('response', response)));
    }
}
//# sourceMappingURL=batch-get-single-table.request.js.map