
pub fn is_address_in_range(addr: u64, range_strings: &Vec<&str>) -> bool {
    for range_str in range_strings {
        if let Some((start, end)) = parse_address_range(range_str) {
            if addr >= start && addr < end {
                return true;
            }
        }
    }
    false
}

fn parse_address_range(range_str: &str) -> Option<(u64, u64)> {
    let parts: Vec<&str> = range_str.split_whitespace().collect();
    if parts.is_empty() {
        return None;
    }

    let range_part = parts[0];

    let range_parts: Vec<&str> = range_part.split('-').collect();
    if range_parts.len() != 2 {
        return None;
    }

    let start_addr = u64::from_str_radix(range_parts[0], 16).ok()?;
    let end_addr = u64::from_str_radix(range_parts[1], 16).ok()?;

    Some((start_addr, end_addr))
}

pub fn first_rw_segment(range_strings: &Vec<&str>) -> Option<(u64, u64)> {
    for range_str in range_strings {
        let parts: Vec<&str> = range_str.split_whitespace().collect();
        if parts.len() < 2 {
            continue;
        }

        let perms = parts[1];
        if perms.starts_with("rw") {
            if let Some((start, end)) = parse_address_range(range_str) {
                return Some((start, end));
            }
        }
    }
    None
}

pub fn first_exec_segment(range_strings: &Vec<&str>) -> Option<(u64, u64)> {
    for range_str in range_strings {
        let parts: Vec<&str> = range_str.split_whitespace().collect();
        if parts.len() < 2 {
            continue;
        }

        let perms = parts[1];
        if perms.contains('x') {
            if let Some((start, end)) = parse_address_range(range_str) {
                return Some((start, end));
            }
        }
    }
    None
}

pub fn module_base_address(range_strings: &Vec<&str>, module_name: &str) -> Option<u64> {
    let mut base_addr: Option<u64> = None;

    for range_str in range_strings {
        let parts: Vec<&str> = range_str.split_whitespace().collect();
        if parts.len() < 6 {
            continue;
        }

        let path = parts.last().unwrap();

        if let Some(filename) = std::path::Path::new(path).file_name().and_then(|f| f.to_str()) {
            if filename.contains(module_name) {
                if let Some((start, _)) = parse_address_range(range_str) {
                    base_addr = match base_addr {
                        Some(current_min) => Some(current_min.min(start)),
                        None => Some(start),
                    };
                }
            }
        }
    }

    base_addr
}
