"use strict";
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
    return new (P || (P = Promise))(function (resolve, reject) {
        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
        function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
        function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
};
Object.defineProperty(exports, "__esModule", { value: true });
/**
 * @packageDocumentation
 * @module @textile/threads-client/models
 */
const grpc_web_1 = require("@improbable-eng/grpc-web");
const api_pb_1 = require("@textile/threads-client-grpc/api_pb");
const Transaction_1 = require("./Transaction");
/**
 * ReadTransaction performs a read-only bulk transaction on the underlying store.
 */
class ReadTransaction extends Transaction_1.Transaction {
    constructor(config, client, dbID, modelName) {
        super(client, dbID, modelName);
        this.config = config;
        this.client = client;
        this.dbID = dbID;
        this.modelName = modelName;
    }
    /**
     * start begins the transaction. All operations between start and end will be applied as a single transaction upon a call to end.
     */
    start() {
        return __awaiter(this, void 0, void 0, function* () {
            const startReq = new api_pb_1.StartTransactionRequest();
            startReq.setDbid(this.dbID);
            startReq.setCollectionname(this.modelName);
            const req = new api_pb_1.ReadTransactionRequest();
            req.setStarttransactionrequest(startReq);
            const metadata = this.config._wrapBrowserHeaders(new grpc_web_1.grpc.Metadata());
            this.client.start(metadata);
            this.client.send(req);
        });
    }
    /**
     * has checks whether a given instance exists in the given store.
     * @param IDs An array of instance ids to check for.
     */
    has(IDs) {
        return __awaiter(this, void 0, void 0, function* () {
            return new Promise((resolve, reject) => {
                const hasReq = new api_pb_1.HasRequest();
                hasReq.setInstanceidsList(IDs);
                const req = new api_pb_1.ReadTransactionRequest();
                req.setHasrequest(hasReq);
                this.client.onMessage((message) => {
                    const reply = message.getHasreply();
                    resolve(reply ? reply.toObject().exists == true : false);
                });
                this.setReject(reject);
                this.client.send(req);
            });
        });
    }
    /**
     * find queries the store for entities matching the given query parameters. See Query for options.
     * @param query The object that describes the query. See Query for options. Alternatively, see QueryJSON for the basic interface.
     */
    find(query) {
        return __awaiter(this, void 0, void 0, function* () {
            return new Promise((resolve, reject) => {
                const findReq = new api_pb_1.FindRequest();
                findReq.setQueryjson(Buffer.from(JSON.stringify(query)));
                const req = new api_pb_1.ReadTransactionRequest();
                req.setFindrequest(findReq);
                this.client.onMessage((message) => {
                    const reply = message.getFindreply();
                    if (reply === undefined) {
                        resolve();
                    }
                    else {
                        const ret = {
                            instancesList: reply
                                .toObject()
                                .instancesList.map((instance) => JSON.parse(Buffer.from(instance, 'base64').toString())),
                        };
                        resolve(ret);
                    }
                });
                this.setReject(reject);
                this.client.send(req);
            });
        });
    }
    /**
     * findByID queries the store for the id of an instance.
     * @param ID The id of the instance to search for.
     */
    findByID(ID) {
        return __awaiter(this, void 0, void 0, function* () {
            return new Promise((resolve, reject) => {
                const findReq = new api_pb_1.FindByIDRequest();
                findReq.setInstanceid(ID);
                const req = new api_pb_1.ReadTransactionRequest();
                req.setFindbyidrequest(findReq);
                this.client.onMessage((message) => {
                    const reply = message.getFindbyidreply();
                    if (reply === undefined) {
                        resolve();
                    }
                    else {
                        const ret = {
                            instance: JSON.parse(Buffer.from(reply.toObject().instance, 'base64').toString()),
                        };
                        resolve(ret);
                    }
                });
                this.setReject(reject);
                this.client.send(req);
            });
        });
    }
}
exports.ReadTransaction = ReadTransaction;
