#!/usr/bin/env node
"use strict";
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
    if (k2 === undefined) k2 = k;
    var desc = Object.getOwnPropertyDescriptor(m, k);
    if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
      desc = { enumerable: true, get: function() { return m[k]; } };
    }
    Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
    if (k2 === undefined) k2 = k;
    o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
    Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
    o["default"] = v;
});
var __importStar = (this && this.__importStar) || (function () {
    var ownKeys = function(o) {
        ownKeys = Object.getOwnPropertyNames || function (o) {
            var ar = [];
            for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
            return ar;
        };
        return ownKeys(o);
    };
    return function (mod) {
        if (mod && mod.__esModule) return mod;
        var result = {};
        if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
        __setModuleDefault(result, mod);
        return result;
    };
})();
Object.defineProperty(exports, "__esModule", { value: true });
const readline = __importStar(require("readline"));
const block_1 = require("../build/src/models/block");
const coin_1 = require("../build/src/models/coin");
const transaction_1 = require("../build/src/models/transaction");
const storage_1 = require("../build/src/services/storage");
const utils_1 = require("../build/src/utils");
const rl = readline.createInterface({ input: process.stdin, output: process.stdout });
function usage(errMsg) {
    console.log('USAGE: ./purgeNetworkData.js [options');
    console.log('OPTIONS:');
    console.log('  --chain <value>      REQUIRED - e.g. BTC, BCH, DOGE, LTC...');
    console.log('  --network <value>    REQUIRED - e.g. mainnet, testnet3, regtest...');
    console.log('  --limit <value>      Number of documents to delete at a time. Default: 250');
    console.log('  --sleep <value>      Sleep time in milliseconds between deletions. Default: 50');
    console.log('  --every <value>      Sleep for --sleep milliseconds every --every loop iteration. Default: 10');
    if (errMsg) {
        console.log('\nERROR: ' + errMsg);
    }
    process.exit();
}
const args = process.argv.slice(2);
if (args.includes('--help') || args.includes('-h')) {
    usage();
}
const chainIdx = args.indexOf('--chain');
const networkIdx = args.indexOf('--network');
const chain = args[chainIdx + 1]?.toUpperCase();
const network = args[networkIdx + 1]?.toLowerCase();
if (chainIdx === -1 || networkIdx === -1 || !chain || !network) {
    usage('Missing required options.');
}
const limitIdx = args.indexOf('--limit');
const limit = (limitIdx > -1 && parseInt(args[limitIdx + 1])) || 250;
const sleepIdx = args.indexOf('--sleep');
const sleepMs = (sleepIdx > -1 && parseInt(args[sleepIdx + 1])) || 50;
const everyIdx = args.indexOf('--every');
const nSleep = (everyIdx > -1 && parseInt(args[everyIdx + 1])) || 10;
let quit = false;
process.on('SIGINT', () => {
    if (quit) {
        process.exit(1);
    }
    console.log('Caught interrupt signal');
    quit = true;
});
console.log('Connecting to database...');
storage_1.Storage.start()
    .then(async () => {
    console.log('Collecting stats. This could take a minute...');
    const blkCount = await block_1.BitcoinBlockStorage.collection.countDocuments({ chain, network });
    const txCount = await transaction_1.TransactionStorage.collection.countDocuments({ chain, network });
    const coinCount = await coin_1.CoinStorage.collection.countDocuments({ chain, network });
    let progressCnt = 0;
    console.log(`If you continue, the following ${chain}:${network} data will be purged:`);
    console.log('Blocks:', blkCount);
    console.log('Transactions:', txCount);
    console.log('Coins:', coinCount);
    console.log(`Data will be deleted in batches of ${limit} documents with a sleep time of ${sleepMs}ms every ${nSleep} iterations.`);
    const ans = await new Promise(r => rl.question('Do you want to continue? (y/N): ', r));
    if (ans?.toLowerCase() !== 'y') {
        console.log('Aborted.');
        return;
    }
    {
        progressCnt = 0;
        let blkIds = await block_1.BitcoinBlockStorage.collection.find({ chain, network }).project({ _id: 1 }).limit(limit).toArray();
        while (blkIds.length && !quit) {
            process.stdout.write(`Blocks: ${(progressCnt / blkCount * 100).toFixed(2)}% (${progressCnt} / ${blkCount})\r`);
            await block_1.BitcoinBlockStorage.collection.deleteMany({ _id: { $in: blkIds.map(a => a._id) } });
            progressCnt += blkIds.length;
            if (progressCnt % nSleep === 0) {
                await (0, utils_1.wait)(sleepMs);
            }
            blkIds = await block_1.BitcoinBlockStorage.collection.find({ chain, network }).project({ _id: 1 }).limit(limit).toArray();
        }
        ;
        if (!quit)
            console.log('\nBlocks purged.');
    }
    {
        progressCnt = 0;
        let txIds = await transaction_1.TransactionStorage.collection.find({ chain, network }).project({ _id: 1 }).limit(limit).toArray();
        while (txIds.length && !quit) {
            process.stdout.write(`Transactions: ${(progressCnt / txCount * 100).toFixed(2)}% (${progressCnt} / ${txCount})\r`);
            await transaction_1.TransactionStorage.collection.deleteMany({ _id: { $in: txIds.map(a => a._id) } });
            progressCnt += txIds.length;
            if (progressCnt % nSleep === 0) {
                await (0, utils_1.wait)(sleepMs);
            }
            txIds = await transaction_1.TransactionStorage.collection.find({ chain, network }).project({ _id: 1 }).limit(limit).toArray();
        }
        if (!quit)
            console.log('\nTransactions purged.');
    }
    {
        progressCnt = 0;
        let coinIds = await coin_1.CoinStorage.collection.find({ chain, network }).project({ _id: 1 }).limit(limit).toArray();
        while (coinIds.length && !quit) {
            process.stdout.write(`Coins: ${(progressCnt / coinCount * 100).toFixed(2)}% (${progressCnt} / ${coinCount})\r`);
            await coin_1.CoinStorage.collection.deleteMany({ _id: { $in: coinIds.map(a => a._id) } });
            progressCnt += coinIds.length;
            if (progressCnt % nSleep === 0) {
                await (0, utils_1.wait)(sleepMs);
            }
            coinIds = await coin_1.CoinStorage.collection.find({ chain, network }).project({ _id: 1 }).limit(limit).toArray();
        }
        if (!quit)
            console.log('\nCoins purged.');
    }
    if (!quit)
        console.log('Data purged.');
})
    .catch(console.error)
    .finally(() => {
    rl.close();
    storage_1.Storage.stop();
});
//# sourceMappingURL=purgeNetworkData.js.map