"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());
    });
};
const newid = require("./newid");
// bypass the main application db config
// use in memory pouchdb directly
const { getPouch, closeDB } = require("@devlego/backend-core/db");
const Pouch = getPouch({ inMemory: true });
exports.runView = (view, calculation, group, data) => __awaiter(void 0, void 0, void 0, function* () {
    // use a different ID each time for the DB, make sure they
    // are always unique for each query, don't want overlap
    // which could cause 409s
    const db = new Pouch(newid());
    try {
        // write all the docs to the in memory Pouch (remove revs)
        yield db.bulkDocs(data.map(row => (Object.assign(Object.assign({}, row), { _rev: undefined }))));
        let fn = (doc, emit) => emit(doc._id);
        eval("fn = " + view.map.replace("function (doc)", "function (doc, emit)"));
        const queryFns = {
            meta: view.meta,
            map: fn,
        };
        if (view.reduce) {
            queryFns.reduce = view.reduce;
        }
        const response = yield db.query(queryFns, {
            include_docs: !calculation,
            group: !!group,
        });
        // need to fix the revs to be totally accurate
        for (let row of response.rows) {
            if (!row._rev || !row._id) {
                continue;
            }
            const found = data.find(possible => possible._id === row._id);
            if (found) {
                row._rev = found._rev;
            }
        }
        return response;
    }
    finally {
        yield db.destroy();
        yield closeDB(db);
    }
});
