"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 (mod) {
    if (mod && mod.__esModule) return mod;
    var result = {};
    if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
    __setModuleDefault(result, mod);
    return result;
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.getProblematicNodes = exports.getRefutePercentage = exports.getConsecutiveRefutes = exports.isNodeProblematic = void 0;
const NodeList = __importStar(require("./NodeList"));
const Context_1 = require("./Context");
function isNodeProblematic(node, currentCycle) {
    if (!node.refuteCycles)
        return false;
    // Check consecutive refutes
    const consecutiveRefutes = getConsecutiveRefutes(node.refuteCycles, currentCycle);
    if (consecutiveRefutes >= Context_1.config.p2p.problematicNodeConsecutiveRefuteThreshold) {
        return true;
    }
    // Check refute percentage in recent history
    const refutePercentage = getRefutePercentage(node.refuteCycles, currentCycle);
    if (refutePercentage >= Context_1.config.p2p.problematicNodeRefutePercentageThreshold) {
        return true;
    }
    return false;
}
exports.isNodeProblematic = isNodeProblematic;
function getConsecutiveRefutes(refuteCycles, currentCycle) {
    if (refuteCycles.length === 0)
        return 0;
    // Filter to only include refutes up to current cycle
    const relevantRefutes = refuteCycles.filter((cycle) => cycle <= currentCycle);
    if (relevantRefutes.length === 0)
        return 0;
    // Find the longest consecutive sequence that ends at current cycle or one before
    let maxCount = 0;
    let currentCount = 1;
    let lastCycle = relevantRefutes[0];
    for (let i = 1; i < relevantRefutes.length; i++) {
        const cycle = relevantRefutes[i];
        if (cycle === lastCycle + 1) {
            currentCount++;
        }
        else {
            // If sequence breaks, check if previous sequence ended at current cycle or one before
            if (lastCycle === currentCycle || lastCycle === currentCycle - 1) {
                maxCount = Math.max(maxCount, currentCount);
            }
            currentCount = 1;
        }
        lastCycle = cycle;
    }
    // Check the last sequence
    if (lastCycle === currentCycle || lastCycle === currentCycle - 1) {
        maxCount = Math.max(maxCount, currentCount);
    }
    return maxCount;
}
exports.getConsecutiveRefutes = getConsecutiveRefutes;
function getRefutePercentage(refuteCycles, currentCycle) {
    const windowStart = Math.max(1, currentCycle - Context_1.config.p2p.problematicNodeHistoryLength);
    const windowSize = Math.min(Context_1.config.p2p.problematicNodeHistoryLength, currentCycle);
    const recentRefutes = refuteCycles.filter((cycle) => cycle >= windowStart && cycle <= currentCycle).length;
    return recentRefutes / windowSize;
}
exports.getRefutePercentage = getRefutePercentage;
function getProblematicNodes(prevRecord) {
    const problematicNodes = NodeList.activeByIdOrder.filter((node) => isNodeProblematic(node, prevRecord.counter));
    // Sort by refute percentage
    return problematicNodes
        .sort((a, b) => {
        const percentageA = getRefutePercentage(a.refuteCycles, prevRecord.counter);
        const percentageB = getRefutePercentage(b.refuteCycles, prevRecord.counter);
        return percentageB - percentageA;
    })
        .map((node) => node.id);
}
exports.getProblematicNodes = getProblematicNodes;
//# sourceMappingURL=ProblemNodeHandler.js.map