def get_roc_for_multi_fprs(
    attack_proba: np.ndarray,
    attack_true: np.ndarray,
    targeted_fprs: np.ndarray,
) -> tuple[list[FPR], list[TPR], list[THR]]:
    """
    Compute the attack ROC based on the targeted FPRs. This implementation supports only binary
    attack prediction labels. The returned list of THRESHOLDs defines the decision threshold on the attack
    probabilities (meaning if p < THRESHOLD predict 0, otherwise predict 1) for each provided fpr

    | Related paper link: https://arxiv.org/abs/2112.03570

    :param attack_proba: Predicted attack probabilities.
    :param attack_true: True attack labels.
    :param targeted_fprs: the set of targeted FPR (False Positive Rates), attack accuracy will be calculated based on
    these FPRs.
    :return: list of tuples that  (TPR, Threshold, Achieved FPR).
    """

    if attack_proba.shape[0] != attack_true.shape[0]:
        raise ValueError("Number of rows in attack_pred and attack_true do not match")

    tpr = []
    thr = []
    fpr = []

    for t_fpr in targeted_fprs:
        res = _calculate_roc_for_fpr(y_proba=attack_proba, y_true=attack_true, targeted_fpr=t_fpr)

        fpr.append(res[0])
        tpr.append(res[1])
        thr.append(res[2])

    return fpr, tpr, thr

    Compute the attack ROC based on the targeted FPRs. This implementation supports only binary
    attack prediction labels. The returned list of THRESHOLDs defines the decision threshold on the attack
    probabilities (meaning if p < THRESHOLD predict 0, otherwise predict 1) for each provided fpr

    | Related paper link: https://arxiv.org/abs/2112.03570

    :param attack_proba: Predicted attack probabilities.
    :param attack_true: True attack labels.
    :param targeted_fprs: the set of targeted FPR (False Positive Rates), attack accuracy will be calculated based on
    these FPRs.
    :return: list of tuples that  (TPR, Threshold, Achieved FPR).
    
art/metrics/privacy/worst_case_mia_score.py