"use strict";
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
    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) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
};
Object.defineProperty(exports, "__esModule", { value: true });
const node_fetch_1 = require("node-fetch");
const assert = require("assert");
const Analytics = require("../analytics/Analytics");
const library_utils_1 = require("../utils/library-utils");
const config_1 = require("../../config");
const storyboard_1 = require("storyboard");
class DatabaseConfigurator {
    constructor(opts) {
        this.opts = opts;
    }
    configure() {
        return __awaiter(this, void 0, void 0, function* () {
            // await this.startServer();
            yield this.endAdminParty();
            yield this.configureDatabases();
            yield this.setupNode();
            yield Analytics.initialize();
            yield library_utils_1.createViews();
            return;
        });
    }
    configureDatabases() {
        // return Promise.all(dbs.map(({name, schema, perms}) => {
        //   const db = new PouchDB(name);
        //   mainStory.info('configure', )
        //   return db.put({
        //     _id: `_design/validator`,
        //     validate_doc_update: createValidator(schema, perms)
        //   } as any);
        // })).then(() => {});
        return Promise.resolve({});
    }
    setupNode() {
        return __awaiter(this, void 0, void 0, function* () {
            storyboard_1.mainStory.info('configure', `Trying to setup node...`);
            const url = `http://${this.opts.couchHost}:${this.opts.couchPort}/_cluster_setup`;
            const body = {
                action: "enable_single_node",
                username: this.opts.adminUsername,
                password: this.opts.adminPassword,
                bind_address: "0.0.0.0",
                singlenode: true,
                port: config_1.default.get('couchPort')
            };
            storyboard_1.mainStory.info('configure', `POST ${url}`, {
                attach: Object.assign({}, body, { password: '<written out>' }),
                attachLevel: 'debug'
            });
            const res = yield node_fetch_1.default(url, {
                method: 'POST',
                headers: {
                    'Content-Type': 'application/json',
                    Authorization: 'Basic ' + new Buffer(this.opts.adminUsername + ':' + this.opts.adminPassword).toString('base64')
                },
                body: JSON.stringify(body)
            }).then((res) => res.json());
            storyboard_1.mainStory.info('configure', 'CouchDB responded with', { attach: res });
        });
    }
    endAdminParty() {
        return __awaiter(this, void 0, void 0, function* () {
            const node = yield this.getNode();
            storyboard_1.mainStory.info('configure', 'Ending admin party...');
            const url = `http://${this.opts.couchHost}:${this.opts.couchPort}/_node/${node}/_config/admins/${this.opts.adminUsername}`;
            storyboard_1.mainStory.info('configure', 'PUT ' + url);
            const res = yield node_fetch_1.default(url, {
                method: 'PUT',
                body: `"${this.opts.adminPassword}"`
            }).then((res) => res.json());
            storyboard_1.mainStory.info('configure', 'CouchDB responded with', { attach: res });
        });
    }
    getNode() {
        storyboard_1.mainStory.info('configure', 'Get node name...');
        const url = `http://${this.opts.couchHost}:${this.opts.couchPort}/_membership`;
        storyboard_1.mainStory.info('configure', 'GET ' + url);
        return node_fetch_1.default(url)
            .then((response) => {
            return response.json();
        }).then((res) => {
            storyboard_1.mainStory.info('configure', 'CouchDB responded with', { attach: res });
            assert.equal(res.all_nodes.length, 1);
            return res.all_nodes[0];
        });
    }
}
exports.DatabaseConfigurator = DatabaseConfigurator;
//# sourceMappingURL=DatabaseConfigurator.js.map