use crate::error::DeltaGoError;
use std::ffi::{CStr, CString};
use std::os::raw::c_char;
use url::Url;

pub fn c_str_to_string(ptr: *const c_char) -> Result<String, DeltaGoError> {
    if ptr.is_null() {
        return Err(DeltaGoError::NullPointer);
    }

    unsafe {
        CStr::from_ptr(ptr)
            .to_str()
            .map_err(DeltaGoError::from)
            .map(|s| s.to_string())
    }
}

pub fn string_to_c_str(s: String) -> *const c_char {
    match CString::new(s) {
        Ok(c_string) => c_string.into_raw(),
        Err(_) => std::ptr::null(),
    }
}

pub fn optional_string_to_c_str(s: Option<String>) -> *const c_char {
    match s {
        Some(string) => string_to_c_str(string),
        None => std::ptr::null(),
    }
}

/// Convert a path string to a URL, handling both file paths and URL schemes
pub fn path_to_url(path: &str) -> Result<Url, String> {
    // First try to parse as-is (might be a full URL like s3://, gs://, etc.)
    if let Ok(url) = Url::parse(path) {
        return Ok(url);
    }
    // If it's not a valid URL, treat it as a file path
    // Convert to absolute path if needed
    let path_buf = std::path::PathBuf::from(path);
    let absolute_path = if path_buf.is_absolute() {
        path_buf
    } else {
        std::env::current_dir()
            .map_err(|e| format!("Failed to get current directory: {}", e))?
            .join(path_buf)
    };
    // Convert to file:// URL
    Url::from_file_path(&absolute_path)
        .map_err(|_| format!("Failed to convert path to URL: {}", path))
}
