import * as querystring from "querystring";
import { ActiveLogger } from "@activeledger/activelogger";
import { ActiveRequest } from "./request";
import { EventEmitter } from "events";
import { ActiveOptions } from "./options";
import { PouchDB } from "./pouchdb";
export class ActiveDSConnect {
    constructor(location) {
        this.location = location;
    }
    info() {
        return new Promise((resolve, reject) => {
            ActiveRequest.send(`${this.location}`, "GET")
                .then((response) => resolve(response.data))
                .catch(error => reject(error));
        });
    }
    createIndex(options = {}) {
        return new Promise((resolve, reject) => {
            ActiveRequest.send(`${this.location}/_index`, "POST", undefined, options)
                .then((response) => resolve(response.data))
                .catch(error => reject(error));
        });
    }
    allDocs(options) {
        return new Promise((resolve, reject) => {
            ActiveRequest.send(`${this.location}/_all_docs`, options ? "POST" : "GET", undefined, options)
                .then((response) => resolve(response.data))
                .catch(error => reject(error));
        });
    }
    get(id, options = {}) {
        return new Promise((resolve, reject) => {
            ActiveRequest.send(`${this.location}/${id}`, "GET", undefined, options)
                .then((response) => resolve(response.data))
                .catch(error => reject(error));
        });
    }
    find(options = {}) {
        return new Promise((resolve, reject) => {
            ActiveRequest.send(`${this.location}/_find`, "POST", undefined, options)
                .then((response) => resolve(response.data))
                .catch(error => reject(error));
        });
    }
    bulkDocs(docs, options = {}) {
        return new Promise((resolve, reject) => {
            ActiveRequest.send(`${this.location}/_bulk_docs`, "POST", undefined, {
                docs,
                options
            })
                .then((response) => resolve(response.data))
                .catch(error => reject(error));
        });
    }
    post(doc) {
        return new Promise((resolve, reject) => {
            ActiveRequest.send(this.location, "POST", undefined, doc)
                .then((response) => resolve(response.data))
                .catch(error => reject(error));
        });
    }
    put(doc) {
        return new Promise((resolve, reject) => {
            ActiveRequest.send(`${this.location}/${doc._id}`, "PUT", undefined, doc)
                .then((response) => resolve(response.data))
                .catch(error => reject(error));
        });
    }
    purge(doc) {
        return new Promise((resolve, reject) => {
            ActiveRequest.send(`${this.location}/${doc._id}`, "DELETE")
                .then((response) => resolve(response.data))
                .catch(error => reject(error));
        });
    }
    static smash(source, target) {
        return new Promise((resolve, reject) => {
            if (ActiveOptions.get("db", {}).selfhost) {
                resolve({ status: "ok" });
            }
            else {
                let sourceDb = new PouchDB(source);
                let targetDb = new PouchDB(target);
                let bulkdocs = [];
                targetDb
                    .destroy()
                    .then(() => {
                    targetDb.close();
                    targetDb = new PouchDB(target);
                    targetDb.info().then(() => {
                        sourceDb.replicate
                            .to(target, {
                            filter: (doc, req) => {
                                if (doc.$activeledger &&
                                    doc.$activeledger.delete &&
                                    doc.$activeledger.rewrite) {
                                    bulkdocs.push(doc.$activeledger.rewrite);
                                    return false;
                                }
                                else {
                                    return true;
                                }
                            }
                        })
                            .then(() => {
                            ActiveLogger.warn(`Restoration : ${bulkdocs.length} streams being corrected`);
                            targetDb.bulkDocs(bulkdocs, { new_edits: false }).then(() => {
                                sourceDb.destroy().then(() => {
                                    targetDb.replicate.to(source).then(() => {
                                        resolve({ ok: true });
                                    });
                                });
                            });
                        });
                    });
                })
                    .catch((e) => reject(e));
            }
        });
    }
    changes(opts) {
        if (opts.live) {
            return new ActiveDSChanges(opts, `${this.location}/_changes`);
        }
        else {
            return new Promise((resolve, reject) => {
                ActiveRequest.send(`${this.location}/_changes?${querystring.stringify(opts)}`, "GET")
                    .then((response) => resolve(response.data))
                    .catch(error => reject(error));
            });
        }
    }
}
export class ActiveDSChanges extends EventEmitter {
    constructor(opts, location, bulk = false) {
        super();
        this.opts = opts;
        this.location = location;
        this.bulk = bulk;
        this.stop = false;
        if (!opts.feed) {
            opts.feed = "longpoll";
        }
        setTimeout(() => {
            this.listen();
        }, 250);
    }
    listen() {
        ActiveRequest.send(`${this.location}?${querystring.stringify(this.opts)}`, "GET")
            .then((response) => {
            if (!this.stop) {
                this.opts.since = response.data.last_seq;
                if (this.bulk) {
                    this.emit("change", response.data);
                }
                else {
                    response.data.results.forEach((elm) => {
                        this.emit("change", {
                            doc: elm.doc,
                            seq: elm.seq
                        });
                    });
                }
                this.listen();
            }
        })
            .catch(error => this.emit("error", error));
    }
    cancel() {
        this.stop = true;
    }
}
//# sourceMappingURL=dsconnect.js.map