"use strict";
var __runInitializers = (this && this.__runInitializers) || function (thisArg, initializers, value) {
    var useValue = arguments.length > 2;
    for (var i = 0; i < initializers.length; i++) {
        value = useValue ? initializers[i].call(thisArg, value) : initializers[i].call(thisArg);
    }
    return useValue ? value : void 0;
};
var __esDecorate = (this && this.__esDecorate) || function (ctor, descriptorIn, decorators, contextIn, initializers, extraInitializers) {
    function accept(f) { if (f !== void 0 && typeof f !== "function") throw new TypeError("Function expected"); return f; }
    var kind = contextIn.kind, key = kind === "getter" ? "get" : kind === "setter" ? "set" : "value";
    var target = !descriptorIn && ctor ? contextIn["static"] ? ctor : ctor.prototype : null;
    var descriptor = descriptorIn || (target ? Object.getOwnPropertyDescriptor(target, contextIn.name) : {});
    var _, done = false;
    for (var i = decorators.length - 1; i >= 0; i--) {
        var context = {};
        for (var p in contextIn) context[p] = p === "access" ? {} : contextIn[p];
        for (var p in contextIn.access) context.access[p] = contextIn.access[p];
        context.addInitializer = function (f) { if (done) throw new TypeError("Cannot add initializers after decoration has completed"); extraInitializers.push(accept(f || null)); };
        var result = (0, decorators[i])(kind === "accessor" ? { get: descriptor.get, set: descriptor.set } : descriptor[key], context);
        if (kind === "accessor") {
            if (result === void 0) continue;
            if (result === null || typeof result !== "object") throw new TypeError("Object expected");
            if (_ = accept(result.get)) descriptor.get = _;
            if (_ = accept(result.set)) descriptor.set = _;
            if (_ = accept(result.init)) initializers.unshift(_);
        }
        else if (_ = accept(result)) {
            if (kind === "field") initializers.unshift(_);
            else descriptor[key] = _;
        }
    }
    if (target) Object.defineProperty(target, contextIn.name, descriptor);
    done = true;
};
var __setFunctionName = (this && this.__setFunctionName) || function (f, name, prefix) {
    if (typeof name === "symbol") name = name.description ? "[".concat(name.description, "]") : "";
    return Object.defineProperty(f, "name", { configurable: true, value: prefix ? "".concat(prefix, " ", name) : name });
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.AbstractFiniteCursor = exports.BaseCursor = void 0;
const decorators_1 = require("./decorators");
const enums_1 = require("./enums");
const result_1 = require("./result");
const helpers_1 = require("./helpers");
let BaseCursor = (() => {
    let _classDecorators = [decorators_1.shellApiClassNoHelp];
    let _classDescriptor;
    let _classExtraInitializers = [];
    let _classThis;
    let _classSuper = decorators_1.ShellApiWithMongoClass;
    let _instanceExtraInitializers = [];
    let _close_decorators;
    let _forEach_decorators;
    let _hasNext_decorators;
    let _tryNext_decorators;
    let _itcount_decorators;
    let _pretty_decorators;
    let _map_decorators;
    let _next_decorators;
    let _disableBlockWarnings_decorators;
    var BaseCursor = _classThis = class extends _classSuper {
        constructor(mongo, cursor, constructionOptionsWithChains) {
            super();
            this._mongo = __runInitializers(this, _instanceExtraInitializers);
            this._transform = null;
            this._blockingWarningDisabled = false;
            this._mongo = mongo;
            this._cursor = cursor;
            this._constructionOptions = constructionOptionsWithChains?.options;
            this._chains = [];
            if (constructionOptionsWithChains?.chains) {
                for (const chain of constructionOptionsWithChains.chains) {
                    this[chain.method](...chain.args);
                }
            }
        }
        async close() {
            await this._cursor.close();
        }
        async forEach(f) {
            for await (const doc of this) {
                if ((await f(doc)) === false) {
                    break;
                }
            }
        }
        async hasNext() {
            return await this._cursor.hasNext();
        }
        async tryNext() {
            return this._tryNext();
        }
        async _tryNext() {
            let result = await this._cursor.tryNext();
            if (result !== null && this._transform !== null) {
                result = await this._transform(result);
            }
            return result;
        }
        _canDelegateIterationToUnderlyingCursor() {
            return this._transform === null;
        }
        get [(_close_decorators = [decorators_1.returnsPromise], _forEach_decorators = [decorators_1.returnsPromise], _hasNext_decorators = [decorators_1.returnsPromise], _tryNext_decorators = [decorators_1.returnsPromise], Symbol.for('@@mongosh.syntheticAsyncIterable'))]() {
            return true;
        }
        async *[Symbol.asyncIterator]() {
            const baseIterator = this._cursor[Symbol.asyncIterator];
            if (baseIterator && this._canDelegateIterationToUnderlyingCursor()) {
                yield* baseIterator.call(this._cursor);
                return;
            }
            let doc;
            while ((doc = await this._tryNext()) != null) {
                yield doc;
            }
        }
        isClosed() {
            return this._cursor.closed;
        }
        isExhausted() {
            return this.isClosed() && this.objsLeftInBatch() === 0;
        }
        async itcount() {
            let count = 0;
            while (await this._tryNext()) {
                count++;
            }
            return count;
        }
        pretty() {
            return this;
        }
        map(f) {
            if (this._transform === null) {
                this._transform = f;
            }
            else {
                const g = this._transform;
                this._transform = (doc) => f(g(doc));
            }
            return this;
        }
        async next() {
            let result = await this._cursor.next();
            if (result !== null && this._transform !== null) {
                result = await this._transform(result);
            }
            return result;
        }
        disableBlockWarnings() {
            this._blockingWarningDisabled = true;
            return this;
        }
    };
    __setFunctionName(_classThis, "BaseCursor");
    (() => {
        const _metadata = typeof Symbol === "function" && Symbol.metadata ? Object.create(_classSuper[Symbol.metadata] ?? null) : void 0;
        _itcount_decorators = [decorators_1.returnsPromise];
        _pretty_decorators = [(0, decorators_1.returnType)('this'), decorators_1.cursorChainable];
        _map_decorators = [(0, decorators_1.returnType)('this'), decorators_1.cursorChainable];
        _next_decorators = [decorators_1.returnsPromise];
        _disableBlockWarnings_decorators = [decorators_1.cursorChainable];
        __esDecorate(_classThis, null, _close_decorators, { kind: "method", name: "close", static: false, private: false, access: { has: obj => "close" in obj, get: obj => obj.close }, metadata: _metadata }, null, _instanceExtraInitializers);
        __esDecorate(_classThis, null, _forEach_decorators, { kind: "method", name: "forEach", static: false, private: false, access: { has: obj => "forEach" in obj, get: obj => obj.forEach }, metadata: _metadata }, null, _instanceExtraInitializers);
        __esDecorate(_classThis, null, _hasNext_decorators, { kind: "method", name: "hasNext", static: false, private: false, access: { has: obj => "hasNext" in obj, get: obj => obj.hasNext }, metadata: _metadata }, null, _instanceExtraInitializers);
        __esDecorate(_classThis, null, _tryNext_decorators, { kind: "method", name: "tryNext", static: false, private: false, access: { has: obj => "tryNext" in obj, get: obj => obj.tryNext }, metadata: _metadata }, null, _instanceExtraInitializers);
        __esDecorate(_classThis, null, _itcount_decorators, { kind: "method", name: "itcount", static: false, private: false, access: { has: obj => "itcount" in obj, get: obj => obj.itcount }, metadata: _metadata }, null, _instanceExtraInitializers);
        __esDecorate(_classThis, null, _pretty_decorators, { kind: "method", name: "pretty", static: false, private: false, access: { has: obj => "pretty" in obj, get: obj => obj.pretty }, metadata: _metadata }, null, _instanceExtraInitializers);
        __esDecorate(_classThis, null, _map_decorators, { kind: "method", name: "map", static: false, private: false, access: { has: obj => "map" in obj, get: obj => obj.map }, metadata: _metadata }, null, _instanceExtraInitializers);
        __esDecorate(_classThis, null, _next_decorators, { kind: "method", name: "next", static: false, private: false, access: { has: obj => "next" in obj, get: obj => obj.next }, metadata: _metadata }, null, _instanceExtraInitializers);
        __esDecorate(_classThis, null, _disableBlockWarnings_decorators, { kind: "method", name: "disableBlockWarnings", static: false, private: false, access: { has: obj => "disableBlockWarnings" in obj, get: obj => obj.disableBlockWarnings }, metadata: _metadata }, null, _instanceExtraInitializers);
        __esDecorate(null, _classDescriptor = { value: _classThis }, _classDecorators, { kind: "class", name: _classThis.name, metadata: _metadata }, null, _classExtraInitializers);
        BaseCursor = _classThis = _classDescriptor.value;
        if (_metadata) Object.defineProperty(_classThis, Symbol.metadata, { enumerable: true, configurable: true, writable: true, value: _metadata });
        __runInitializers(_classThis, _classExtraInitializers);
    })();
    return BaseCursor = _classThis;
})();
exports.BaseCursor = BaseCursor;
let AbstractFiniteCursor = (() => {
    let _classDecorators = [decorators_1.shellApiClassNoHelp];
    let _classDescriptor;
    let _classExtraInitializers = [];
    let _classThis;
    let _classSuper = BaseCursor;
    let _instanceExtraInitializers = [];
    let _batchSize_decorators;
    let _toArray_decorators;
    let _maxTimeMS_decorators;
    var AbstractFiniteCursor = _classThis = class extends _classSuper {
        constructor(mongo, cursor, constructionOptionsWithChains) {
            super(mongo, cursor, constructionOptionsWithChains);
            this._currentIterationResult = (__runInitializers(this, _instanceExtraInitializers), null);
        }
        async [enums_1.asPrintable]() {
            return (await (0, decorators_1.toShellResult)(this._currentIterationResult ?? (await this._it()))).printable;
        }
        async _it() {
            const results = (this._currentIterationResult =
                new result_1.CursorIterationResult());
            await (0, helpers_1.iterate)(results, this, await this._mongo._displayBatchSize());
            results.cursorHasMore = !this.isExhausted();
            return results;
        }
        batchSize(size) {
            this._cursor.batchSize(size);
            return this;
        }
        async toArray() {
            if (typeof this._cursor.toArray === 'function' &&
                this._canDelegateIterationToUnderlyingCursor()) {
                return await this._cursor.toArray();
            }
            const result = [];
            for await (const doc of this) {
                result.push(doc);
            }
            return result;
        }
        maxTimeMS(value) {
            this._cursor.maxTimeMS(value);
            return this;
        }
        objsLeftInBatch() {
            return this._cursor.bufferedCount();
        }
    };
    __setFunctionName(_classThis, "AbstractFiniteCursor");
    (() => {
        const _metadata = typeof Symbol === "function" && Symbol.metadata ? Object.create(_classSuper[Symbol.metadata] ?? null) : void 0;
        _batchSize_decorators = [(0, decorators_1.returnType)('this'), decorators_1.cursorChainable];
        _toArray_decorators = [decorators_1.returnsPromise];
        _maxTimeMS_decorators = [(0, decorators_1.returnType)('this'), decorators_1.cursorChainable];
        __esDecorate(_classThis, null, _batchSize_decorators, { kind: "method", name: "batchSize", static: false, private: false, access: { has: obj => "batchSize" in obj, get: obj => obj.batchSize }, metadata: _metadata }, null, _instanceExtraInitializers);
        __esDecorate(_classThis, null, _toArray_decorators, { kind: "method", name: "toArray", static: false, private: false, access: { has: obj => "toArray" in obj, get: obj => obj.toArray }, metadata: _metadata }, null, _instanceExtraInitializers);
        __esDecorate(_classThis, null, _maxTimeMS_decorators, { kind: "method", name: "maxTimeMS", static: false, private: false, access: { has: obj => "maxTimeMS" in obj, get: obj => obj.maxTimeMS }, metadata: _metadata }, null, _instanceExtraInitializers);
        __esDecorate(null, _classDescriptor = { value: _classThis }, _classDecorators, { kind: "class", name: _classThis.name, metadata: _metadata }, null, _classExtraInitializers);
        AbstractFiniteCursor = _classThis = _classDescriptor.value;
        if (_metadata) Object.defineProperty(_classThis, Symbol.metadata, { enumerable: true, configurable: true, writable: true, value: _metadata });
        __runInitializers(_classThis, _classExtraInitializers);
    })();
    return AbstractFiniteCursor = _classThis;
})();
exports.AbstractFiniteCursor = AbstractFiniteCursor;
//# sourceMappingURL=abstract-cursor.js.map