use crate::functions::begin_type_pack_alt_d::begin_type_pack_id_txn_log;
use crate::functions::end_type_pack::end_type_pack_id;
use crate::functions::is_optional::is_optional;
use crate::functions::is_variadic_tail::is_variadic_tail;
use crate::records::txn_log::TxnLog;
use crate::type_aliases::type_pack_id::TypePackId;

pub fn get_parameter_extents(
    log: *const TxnLog,
    tp: TypePackId,
    include_hidden_variadics: bool,
) -> (usize, Option<usize>) {
    let mut min_count = 0usize;
    let mut optional_count = 0usize;

    let mut it = begin_type_pack_id_txn_log(tp, log);
    let end_iter = end_type_pack_id(tp);

    while it.operator_ne(&end_iter) {
        let ty = *it.operator_deref();
        if is_optional(ty) {
            optional_count += 1;
        } else {
            min_count += optional_count;
            optional_count = 0;
            min_count += 1;
        }

        it.operator_inc();
    }

    if it
        .tail()
        .map(|tail_tp| is_variadic_tail(tail_tp, unsafe { &*log }, include_hidden_variadics))
        .unwrap_or(false)
    {
        (min_count, None)
    } else {
        (min_count, Some(min_count + optional_count))
    }
}
