"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 });
const errors_1 = require("@mongosh/errors");
const decorators_1 = require("./decorators");
const enums_1 = require("./enums");
const aggregate_or_find_cursor_1 = require("./aggregate-or-find-cursor");
let Cursor = (() => {
    let _classDecorators = [decorators_1.shellApiClassDefault];
    let _classDescriptor;
    let _classExtraInitializers = [];
    let _classThis;
    let _classSuper = aggregate_or_find_cursor_1.AggregateOrFindCursor;
    let _instanceExtraInitializers = [];
    let _addOption_decorators;
    let _allowDiskUse_decorators;
    let _allowPartialResults_decorators;
    let _collation_decorators;
    let _comment_decorators;
    let _count_decorators;
    let _hasNext_decorators;
    let _hint_decorators;
    let _limit_decorators;
    let _max_decorators;
    let _maxAwaitTimeMS_decorators;
    let _min_decorators;
    let _next_decorators;
    let _noCursorTimeout_decorators;
    let _oplogReplay_decorators;
    let _readPref_decorators;
    let _returnKey_decorators;
    let _size_decorators;
    let _tailable_decorators;
    let _maxScan_decorators;
    let _showRecordId_decorators;
    let _readConcern_decorators;
    var Cursor = _classThis = class extends _classSuper {
        constructor(mongo, cursor, constructionOptionsWithChains) {
            super(mongo, cursor, constructionOptionsWithChains);
            this._tailable = (__runInitializers(this, _instanceExtraInitializers), false);
        }
        toJSON() {
            throw new errors_1.MongoshInvalidInputError('Cannot serialize a cursor to JSON. Did you mean to call .toArray() first?', errors_1.CommonErrors.InvalidArgument);
        }
        _addFlag(flag) {
            this._cursor.addCursorFlag(flag, true);
        }
        addOption(optionFlagNumber) {
            if (optionFlagNumber === 4) {
                throw new errors_1.MongoshUnimplementedError('the slaveOk option is not supported.', errors_1.CommonErrors.NotImplemented);
            }
            const optionFlag = enums_1.CURSOR_FLAGS[optionFlagNumber];
            if (!optionFlag) {
                throw new errors_1.MongoshInvalidInputError(`Unknown option flag number: ${optionFlagNumber}.`, errors_1.CommonErrors.InvalidArgument);
            }
            this._cursor.addCursorFlag(optionFlag, true);
            return this;
        }
        allowDiskUse(allow) {
            this._cursor.allowDiskUse(allow);
            return this;
        }
        allowPartialResults() {
            this._addFlag('partial');
            return this;
        }
        collation(spec) {
            this._cursor.collation(spec);
            return this;
        }
        comment(cmt) {
            this._cursor.comment(cmt);
            return this;
        }
        async count() {
            return await this._cursor.count();
        }
        async hasNext() {
            if (this._tailable && !this._blockingWarningDisabled) {
                await this._instanceState.printWarning('If this is a tailable cursor with awaitData, and there are no documents in the batch, this method ' +
                    'will will block. Use tryNext if you want to check if there are any documents without waiting, or ' +
                    'cursor.disableBlockWarnings() if you want to disable this warning.');
            }
            return super.hasNext();
        }
        hint(index) {
            this._cursor.hint(index);
            return this;
        }
        limit(value) {
            this._cursor.limit(value);
            return this;
        }
        max(indexBounds) {
            this._cursor.max(indexBounds);
            return this;
        }
        maxAwaitTimeMS(value) {
            this._cursor.maxAwaitTimeMS(value);
            return this;
        }
        min(indexBounds) {
            this._cursor.min(indexBounds);
            return this;
        }
        async next() {
            if (this._tailable && !this._blockingWarningDisabled) {
                await this._instanceState.printWarning('If this is a tailable cursor with awaitData, and there are no documents in the batch, this' +
                    ' method will will block. Use tryNext if you want to check if there are any documents without waiting,' +
                    ' or cursor.disableBlockWarnings() if you want to disable this warning.');
            }
            return super.next();
        }
        noCursorTimeout() {
            this._addFlag('noCursorTimeout');
            return this;
        }
        oplogReplay() {
            this._addFlag('oplogReplay');
            return this;
        }
        readPref(mode, tagSet, hedgeOptions) {
            let pref;
            if (tagSet || hedgeOptions) {
                pref = this._mongo._serviceProvider.readPreferenceFromOptions({
                    readPreference: mode,
                    readPreferenceTags: tagSet,
                    hedge: hedgeOptions,
                });
            }
            else {
                pref = mode;
            }
            this._cursor = this._cursor.withReadPreference(pref);
            return this;
        }
        returnKey(enabled) {
            this._cursor.returnKey(enabled);
            return this;
        }
        async size() {
            return await this._cursor.count();
        }
        tailable(opts = { awaitData: false }) {
            this._tailable = true;
            this._addFlag('tailable');
            if (opts.awaitData) {
                this._addFlag('awaitData');
            }
            return this;
        }
        maxScan() {
            throw new errors_1.MongoshDeprecatedError('`maxScan()` was removed because it was deprecated in MongoDB 4.0');
        }
        showRecordId() {
            this._cursor.showRecordId(true);
            return this;
        }
        readConcern(level) {
            this._cursor = this._cursor.withReadConcern({ level });
            return this;
        }
    };
    __setFunctionName(_classThis, "Cursor");
    (() => {
        const _metadata = typeof Symbol === "function" && Symbol.metadata ? Object.create(_classSuper[Symbol.metadata] ?? null) : void 0;
        _addOption_decorators = [(0, decorators_1.returnType)('Cursor'), (0, decorators_1.serverVersions)([enums_1.ServerVersions.earliest, '3.2.0']), decorators_1.cursorChainable];
        _allowDiskUse_decorators = [(0, decorators_1.returnType)('Cursor'), (0, decorators_1.serverVersions)(['4.4.0', enums_1.ServerVersions.latest]), decorators_1.cursorChainable];
        _allowPartialResults_decorators = [(0, decorators_1.returnType)('Cursor'), decorators_1.cursorChainable];
        _collation_decorators = [(0, decorators_1.returnType)('Cursor'), (0, decorators_1.serverVersions)(['3.4.0', enums_1.ServerVersions.latest]), decorators_1.cursorChainable];
        _comment_decorators = [(0, decorators_1.returnType)('Cursor'), (0, decorators_1.serverVersions)(['3.2.0', enums_1.ServerVersions.latest]), decorators_1.cursorChainable];
        _count_decorators = [(0, decorators_1.serverVersions)([enums_1.ServerVersions.earliest, '4.0.0']), decorators_1.returnsPromise, decorators_1.deprecated];
        _hasNext_decorators = [decorators_1.returnsPromise];
        _hint_decorators = [(0, decorators_1.returnType)('Cursor'), decorators_1.cursorChainable];
        _limit_decorators = [(0, decorators_1.returnType)('Cursor'), decorators_1.cursorChainable];
        _max_decorators = [(0, decorators_1.returnType)('Cursor'), decorators_1.cursorChainable];
        _maxAwaitTimeMS_decorators = [(0, decorators_1.returnType)('Cursor'), (0, decorators_1.serverVersions)(['3.2.0', enums_1.ServerVersions.latest]), decorators_1.cursorChainable];
        _min_decorators = [(0, decorators_1.returnType)('Cursor'), decorators_1.cursorChainable];
        _next_decorators = [decorators_1.returnsPromise];
        _noCursorTimeout_decorators = [(0, decorators_1.returnType)('Cursor'), decorators_1.cursorChainable];
        _oplogReplay_decorators = [(0, decorators_1.returnType)('Cursor'), decorators_1.cursorChainable];
        _readPref_decorators = [(0, decorators_1.returnType)('Cursor'), decorators_1.cursorChainable];
        _returnKey_decorators = [(0, decorators_1.returnType)('Cursor'), (0, decorators_1.serverVersions)(['3.2.0', enums_1.ServerVersions.latest]), decorators_1.cursorChainable];
        _size_decorators = [decorators_1.returnsPromise];
        _tailable_decorators = [(0, decorators_1.returnType)('Cursor'), (0, decorators_1.serverVersions)(['3.2.0', enums_1.ServerVersions.latest]), (0, decorators_1.apiVersions)([]), decorators_1.cursorChainable];
        _maxScan_decorators = [decorators_1.deprecated, (0, decorators_1.serverVersions)([enums_1.ServerVersions.earliest, '4.0.0'])];
        _showRecordId_decorators = [(0, decorators_1.returnType)('Cursor'), (0, decorators_1.serverVersions)(['3.2.0', enums_1.ServerVersions.latest]), decorators_1.cursorChainable];
        _readConcern_decorators = [(0, decorators_1.returnType)('Cursor'), decorators_1.cursorChainable];
        __esDecorate(_classThis, null, _addOption_decorators, { kind: "method", name: "addOption", static: false, private: false, access: { has: obj => "addOption" in obj, get: obj => obj.addOption }, metadata: _metadata }, null, _instanceExtraInitializers);
        __esDecorate(_classThis, null, _allowDiskUse_decorators, { kind: "method", name: "allowDiskUse", static: false, private: false, access: { has: obj => "allowDiskUse" in obj, get: obj => obj.allowDiskUse }, metadata: _metadata }, null, _instanceExtraInitializers);
        __esDecorate(_classThis, null, _allowPartialResults_decorators, { kind: "method", name: "allowPartialResults", static: false, private: false, access: { has: obj => "allowPartialResults" in obj, get: obj => obj.allowPartialResults }, metadata: _metadata }, null, _instanceExtraInitializers);
        __esDecorate(_classThis, null, _collation_decorators, { kind: "method", name: "collation", static: false, private: false, access: { has: obj => "collation" in obj, get: obj => obj.collation }, metadata: _metadata }, null, _instanceExtraInitializers);
        __esDecorate(_classThis, null, _comment_decorators, { kind: "method", name: "comment", static: false, private: false, access: { has: obj => "comment" in obj, get: obj => obj.comment }, metadata: _metadata }, null, _instanceExtraInitializers);
        __esDecorate(_classThis, null, _count_decorators, { kind: "method", name: "count", static: false, private: false, access: { has: obj => "count" in obj, get: obj => obj.count }, 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, _hint_decorators, { kind: "method", name: "hint", static: false, private: false, access: { has: obj => "hint" in obj, get: obj => obj.hint }, metadata: _metadata }, null, _instanceExtraInitializers);
        __esDecorate(_classThis, null, _limit_decorators, { kind: "method", name: "limit", static: false, private: false, access: { has: obj => "limit" in obj, get: obj => obj.limit }, metadata: _metadata }, null, _instanceExtraInitializers);
        __esDecorate(_classThis, null, _max_decorators, { kind: "method", name: "max", static: false, private: false, access: { has: obj => "max" in obj, get: obj => obj.max }, metadata: _metadata }, null, _instanceExtraInitializers);
        __esDecorate(_classThis, null, _maxAwaitTimeMS_decorators, { kind: "method", name: "maxAwaitTimeMS", static: false, private: false, access: { has: obj => "maxAwaitTimeMS" in obj, get: obj => obj.maxAwaitTimeMS }, metadata: _metadata }, null, _instanceExtraInitializers);
        __esDecorate(_classThis, null, _min_decorators, { kind: "method", name: "min", static: false, private: false, access: { has: obj => "min" in obj, get: obj => obj.min }, 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, _noCursorTimeout_decorators, { kind: "method", name: "noCursorTimeout", static: false, private: false, access: { has: obj => "noCursorTimeout" in obj, get: obj => obj.noCursorTimeout }, metadata: _metadata }, null, _instanceExtraInitializers);
        __esDecorate(_classThis, null, _oplogReplay_decorators, { kind: "method", name: "oplogReplay", static: false, private: false, access: { has: obj => "oplogReplay" in obj, get: obj => obj.oplogReplay }, metadata: _metadata }, null, _instanceExtraInitializers);
        __esDecorate(_classThis, null, _readPref_decorators, { kind: "method", name: "readPref", static: false, private: false, access: { has: obj => "readPref" in obj, get: obj => obj.readPref }, metadata: _metadata }, null, _instanceExtraInitializers);
        __esDecorate(_classThis, null, _returnKey_decorators, { kind: "method", name: "returnKey", static: false, private: false, access: { has: obj => "returnKey" in obj, get: obj => obj.returnKey }, metadata: _metadata }, null, _instanceExtraInitializers);
        __esDecorate(_classThis, null, _size_decorators, { kind: "method", name: "size", static: false, private: false, access: { has: obj => "size" in obj, get: obj => obj.size }, metadata: _metadata }, null, _instanceExtraInitializers);
        __esDecorate(_classThis, null, _tailable_decorators, { kind: "method", name: "tailable", static: false, private: false, access: { has: obj => "tailable" in obj, get: obj => obj.tailable }, metadata: _metadata }, null, _instanceExtraInitializers);
        __esDecorate(_classThis, null, _maxScan_decorators, { kind: "method", name: "maxScan", static: false, private: false, access: { has: obj => "maxScan" in obj, get: obj => obj.maxScan }, metadata: _metadata }, null, _instanceExtraInitializers);
        __esDecorate(_classThis, null, _showRecordId_decorators, { kind: "method", name: "showRecordId", static: false, private: false, access: { has: obj => "showRecordId" in obj, get: obj => obj.showRecordId }, metadata: _metadata }, null, _instanceExtraInitializers);
        __esDecorate(_classThis, null, _readConcern_decorators, { kind: "method", name: "readConcern", static: false, private: false, access: { has: obj => "readConcern" in obj, get: obj => obj.readConcern }, metadata: _metadata }, null, _instanceExtraInitializers);
        __esDecorate(null, _classDescriptor = { value: _classThis }, _classDecorators, { kind: "class", name: _classThis.name, metadata: _metadata }, null, _classExtraInitializers);
        Cursor = _classThis = _classDescriptor.value;
        if (_metadata) Object.defineProperty(_classThis, Symbol.metadata, { enumerable: true, configurable: true, writable: true, value: _metadata });
        __runInitializers(_classThis, _classExtraInitializers);
    })();
    return Cursor = _classThis;
})();
exports.default = Cursor;
//# sourceMappingURL=cursor.js.map