"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
require("dotenv/config");
require("reflect-metadata");
const data_source_1 = require("../infrastructure/persistence/data-source");
const pino_logger_1 = require("../infrastructure/logging/pino-logger");
const transaction_entity_1 = require("../infrastructure/persistence/entities/transaction.entity");
const token_entity_1 = require("../infrastructure/persistence/entities/token.entity");
const transaction_data_1 = require("../domain/value-objects/transaction-data");
const DRY_RUN = process.env.DRY_RUN === 'true';
const run = async () => {
    await (0, data_source_1.initializeDatabase)();
    const logger = new pino_logger_1.PinoLogger();
    const transactionRepository = data_source_1.AppDataSource.getRepository(transaction_entity_1.TransactionEntity);
    const tokenRepository = data_source_1.AppDataSource.getRepository(token_entity_1.TokenEntity);
    const [transactions, tokens] = await Promise.all([
        transactionRepository.find(),
        tokenRepository.find(),
    ]);
    const tokenById = new Map(tokens.map((t) => [t.id, t]));
    logger.info('Starting transaction network healing', {
        dryRun: DRY_RUN,
        transactions: transactions.length,
        tokens: tokens.length,
    });
    const resolveExpectedNetworkId = (entity) => {
        if (entity.interactedWith) {
            const token = tokenById.get(entity.interactedWith);
            if (token) {
                return token.networkId;
            }
        }
        for (const path of entity.data) {
            // Swap-style token transfer paths carry token ids in from/to.
            if ((0, transaction_data_1.isTokenTransferPath)(path)) {
                const token = tokenById.get(path.from) ?? tokenById.get(path.to);
                if (token) {
                    return token.networkId;
                }
            }
        }
        return null;
    };
    let healed = 0;
    let skipped = 0;
    let failed = 0;
    let undetermined = 0;
    for (const entity of transactions) {
        const expectedNetworkId = resolveExpectedNetworkId(entity);
        if (!expectedNetworkId) {
            undetermined++;
            logger.warn('Could not determine expected network for transaction', {
                id: entity.id,
                currentNetworkId: entity.networkId,
            });
            continue;
        }
        if (entity.networkId === expectedNetworkId) {
            skipped++;
            continue;
        }
        const oldNetworkId = entity.networkId;
        if (DRY_RUN) {
            logger.info('[DRY RUN] Would heal transaction network', {
                id: entity.id,
                hash: entity.hash,
                oldNetworkId,
                newNetworkId: expectedNetworkId,
            });
            healed++;
            continue;
        }
        entity.networkId = expectedNetworkId;
        entity.updatedAt = new Date();
        try {
            await transactionRepository.save(entity);
            logger.info('Healed transaction network', {
                id: entity.id,
                hash: entity.hash,
                oldNetworkId,
                newNetworkId: expectedNetworkId,
            });
            healed++;
        }
        catch (error) {
            logger.error('Failed to heal transaction network', {
                id: entity.id,
                hash: entity.hash,
                oldNetworkId,
                newNetworkId: expectedNetworkId,
                error,
            });
            failed++;
            entity.networkId = oldNetworkId;
        }
    }
    logger.info('Transaction network healing complete', {
        dryRun: DRY_RUN,
        transactions: transactions.length,
        healed,
        skipped,
        failed,
        undetermined,
    });
    process.exit(failed > 0 ? 1 : 0);
};
run().catch((error) => {
    // eslint-disable-next-line no-console
    console.error('Transaction network healing failed', error);
    process.exit(1);
});
//# sourceMappingURL=heal-transaction-networks.js.map