use crate::apple_helpers::__msg_send_parse;
use crate::apple_helpers::msg_send;
use crate::apple_helpers::{ns_string_to_string, Object};
use libc::{strlen, PATH_MAX};
use objc2::class;
use std::ffi::{c_char, c_int, OsStr};
use std::os::unix::ffi::OsStrExt;
use std::path::PathBuf;
extern "C" {
pub fn _NSGetExecutablePath(buf: *mut c_char, bufsize: *mut u32) -> c_int;
}
pub fn get_exe_path() -> Option<PathBuf> {
let mut buf: [c_char; PATH_MAX as usize] = [0; PATH_MAX as usize];
let mut size: u32 = PATH_MAX as u32;
unsafe {
let res = _NSGetExecutablePath(&mut buf as _, &mut size as _);
if res == -1 {
let mut v = Vec::with_capacity(size as usize);
let res = _NSGetExecutablePath(v.as_mut_ptr(), &mut size as _);
if res != 0 {
return None;
}
let str = OsStr::from_bytes(std::mem::transmute(&v[..size as usize]));
return PathBuf::from(str).parent().map(|v| v.into());
}
if res != 0 {
return None;
}
let len = strlen(buf.as_ptr());
let str = OsStr::from_bytes(std::mem::transmute(&buf[..len]));
PathBuf::from(str).parent().map(|v| v.into())
}
}
pub fn get_resources_dir() -> Option<PathBuf> {
unsafe {
let nsbundle = class!(NSBundle);
let bundle: Option<&Object> = msg_send![nsbundle, mainBundle];
let bundle = bundle?;
let str: Option<&Object> = msg_send![bundle, resourcePath];
let str = str?;
Some(PathBuf::from(ns_string_to_string(str)))
}
}