/*
 * Copyright (c) 2026 Huawei Technologies Co., Ltd.
 * openFuyao is licensed under Mulan PSL v2.
 * You can use this software according to the terms and conditions of the Mulan PSL v2.
 * You may obtain a copy of Mulan PSL v2 at:
 *          http://license.coscl.org.cn/MulanPSL2
 * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
 * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
 * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
 * See the Mulan PSL v2 for more details.
 */

use std::env;
use std::fs;
use std::path::Path;

#[derive(Debug, Clone)]
pub struct Availability {
    pub available: bool,
    pub reason: String,
}

pub fn probe_availability() -> Availability {
    if env::var("WD_FORCE_TCP_FALLBACK")
        .map(|value| value.eq_ignore_ascii_case("true") || value == "1")
        .unwrap_or(false)
    {
        return Availability {
            available: false,
            reason: "forced tcp fallback by env".to_string(),
        };
    }

    let has_rdma_build = env!("WD_HAS_RDMA") == "1";
    if !has_rdma_build {
        return Availability {
            available: false,
            reason: "rdma libraries were not found at build time".to_string(),
        };
    }

    if !Path::new("/dev/infiniband").exists() {
        return Availability {
            available: false,
            reason: "/dev/infiniband is not mounted".to_string(),
        };
    }

    let entries = match fs::read_dir("/dev/infiniband") {
        Ok(entries) => entries,
        Err(err) => {
            return Availability {
                available: false,
                reason: format!("failed to read /dev/infiniband: {err}"),
            }
        }
    };

    let has_device = entries.filter_map(Result::ok).any(|entry| {
        let file_name = entry.file_name();
        let name = file_name.to_string_lossy();
        name.starts_with("uverbs") || name.starts_with("rdma_cm")
    });
    if !has_device {
        return Availability {
            available: false,
            reason: "no uverbs or rdma_cm devices found".to_string(),
        };
    }

    let sysfs_path = env::var("WD_RDMA_NETDEV")
        .ok()
        .filter(|value| !value.is_empty())
        .map(|value| format!("/sys/class/net/{value}"))
        .unwrap_or_else(|| "/sys/class/net".to_string());
    if !Path::new(&sysfs_path).exists() {
        return Availability {
            available: false,
            reason: format!("network sysfs path {sysfs_path} is not available"),
        };
    }

    Availability {
        available: true,
        reason: "rdma devices and libraries detected".to_string(),
    }
}