"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
    return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.MonitorDaemon = void 0;
const knex_1 = require("knex");
const dotenv_1 = __importDefault(require("dotenv"));
const StorageKnex_1 = require("../storage/StorageKnex");
const WalletStorageManager_1 = require("../storage/WalletStorageManager");
const Services_1 = require("../services/Services");
const Monitor_1 = require("./Monitor");
const WERR_errors_1 = require("../sdk/WERR_errors");
const utilityHelpers_1 = require("../utility/utilityHelpers");
const WalletError_1 = require("../sdk/WalletError");
dotenv_1.default.config();
const mainDojoConnection = process.env.MAIN_DOJO_CONNECTION || '';
const testDojoConnection = process.env.TEST_DOJO_CONNECTION || '';
class MonitorDaemon {
    constructor(args, noRunTasks) {
        this.args = args;
        this.noRunTasks = noRunTasks;
        this.stopDaemon = false;
        /* */
    }
    async createSetup() {
        var _a;
        this.setup = { ...this.args };
        const a = this.setup;
        if (!a.monitor) {
            a.chain || (a.chain = 'test');
            if (a.sqliteFilename) {
                a.knexConfig = {
                    client: 'better-sqlite3',
                    connection: { filename: a.sqliteFilename },
                    useNullAsDefault: true
                };
            }
            if (a.mySQLConnection) {
                a.knexConfig = {
                    client: 'mysql2',
                    connection: JSON.parse(a.mySQLConnection),
                    useNullAsDefault: true,
                    pool: { min: 0, max: 7, idleTimeoutMillis: 15000 }
                };
            }
            if (a.knexConfig) {
                a.knex = (0, knex_1.knex)(a.knexConfig);
            }
            if (a.knex) {
                a.storageKnexOptions = {
                    knex: a.knex,
                    chain: a.chain,
                    feeModel: { model: 'sat/kb', value: 1 },
                    commissionSatoshis: 0
                };
            }
            if (a.storageKnexOptions) {
                a.storageProvider = new StorageKnex_1.StorageKnex(a.storageKnexOptions);
            }
            if (a.storageProvider) {
                await a.storageProvider.makeAvailable();
                const settings = await a.storageProvider.getSettings();
                a.storageManager = new WalletStorageManager_1.WalletStorageManager(settings.storageIdentityKey, a.storageProvider);
                await a.storageManager.makeAvailable();
            }
            else if (!a.storageManager) {
                throw new WERR_errors_1.WERR_INVALID_PARAMETER('storageManager', 'valid or one of mySQLConnection, knexConfig, knex, storageKnexOptions, or storageProvider');
            }
            if (a.servicesOptions) {
                if (a.servicesOptions.chain != a.chain)
                    throw new WERR_errors_1.WERR_INVALID_PARAMETER('serviceOptions.chain', 'same as args.chain');
                (_a = a.servicesOptions).chaintracks || (_a.chaintracks = a.chaintracks);
                a.services = new Services_1.Services(a.servicesOptions);
            }
            if (!a.services) {
                a.services = new Services_1.Services(a.chain);
            }
            a.storageManager.setServices(a.services);
            const monitorOptions = Monitor_1.Monitor.createDefaultWalletMonitorOptions(a.chain, a.storageManager, a.services, a.chaintracks);
            a.monitor = new Monitor_1.Monitor(monitorOptions);
        }
        if (a.monitor._tasks.length === 0) {
            a.monitor.addMultiUserTasks();
        }
    }
    async start() {
        var _a;
        if (!this.setup)
            await this.createSetup();
        if (!((_a = this.setup) === null || _a === void 0 ? void 0 : _a.monitor))
            throw new WERR_errors_1.WERR_INTERNAL('createSetup failed to initialize setup');
        const { monitor } = this.setup;
        if (!this.noRunTasks) {
            console.log('\n\nRunning startTasks\n\n');
            this.doneTasks = monitor.startTasks();
        }
    }
    async stop() {
        console.log('start of stop');
        if (!this.setup || (!this.doneTasks && !this.noRunTasks) || !this.doneListening)
            throw new WERR_errors_1.WERR_INTERNAL('call start or createSetup first');
        const { monitor } = this.setup;
        monitor.stopTasks();
        if (this.doneTasks)
            await this.doneTasks;
        this.doneTasks = undefined;
        await this.doneListening;
        this.doneListening = undefined;
    }
    async destroy() {
        if (!this.setup)
            return;
        if (this.doneTasks || this.doneListening)
            await this.stop();
        if (this.setup.storageProvider)
            this.setup.storageProvider.destroy();
        this.setup = undefined;
    }
    async runDaemon() {
        this.stopDaemon = false;
        for (;;) {
            try {
                await this.start();
                while (!this.stopDaemon) {
                    await (0, utilityHelpers_1.wait)(10 * 1000);
                }
                console.log('stopping');
                await this.stop();
                console.log('cleanup');
                await this.destroy();
                console.log('done');
            }
            catch (eu) {
                const e = WalletError_1.WalletError.fromUnknown(eu);
                console.log(`\n\nrunWatchman Main Error Handler\n\ncode: ${e.code}\nDescription: ${e.description}\n\n\n`);
            }
        }
    }
}
exports.MonitorDaemon = MonitorDaemon;
//# sourceMappingURL=MonitorDaemon.js.map