def _calculate_roc_for_fpr(y_true: np.ndarray, y_proba: np.ndarray, targeted_fpr: float) -> tuple[FPR, TPR, THR]:
    """
    Get FPR, TPR and, THRESHOLD based on the targeted_fpr (such that FPR <= targeted_fpr)
    :param y_true: True attack labels.
    :param y_proba: Predicted attack probabilities.
    :param targeted_fpr: the targeted False Positive Rate, ROC will be calculated based on this FPR.
    :return: Tuple that contains (Achieved FPR, TPR, Threshold).
    """

    fpr, tpr, thr = roc_curve(y_true=y_true, y_score=y_proba)
    # take the highest fpr and an appropriated threshold that achieve at least FPR=fpr
    if np.isnan(fpr).all() or np.isnan(tpr).all():
        logging.error("TPR or FPR values are NaN")
        raise ValueError("The targeted FPR can't be achieved.")

    targeted_fpr_idx = np.where(fpr <= targeted_fpr)[0][-1]
    return fpr[targeted_fpr_idx], tpr[targeted_fpr_idx], thr[targeted_fpr_idx]

    Get FPR, TPR and, THRESHOLD based on the targeted_fpr (such that FPR <= targeted_fpr)
    :param y_true: True attack labels.
    :param y_proba: Predicted attack probabilities.
    :param targeted_fpr: the targeted False Positive Rate, ROC will be calculated based on this FPR.
    :return: Tuple that contains (Achieved FPR, TPR, Threshold).
    
art/metrics/privacy/worst_case_mia_score.py