/* macos.rs
 *
 * Copyright 2026 Christian Kruse
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Affero General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with this program.  If not, see <https://www.gnu.org/licenses/>.
 *
 * SPDX-License-Identifier: AGPL-3.0-or-later
 */

use std::path::PathBuf;

use crate::config::{LOCALEDIR, PKGDATADIR};

pub struct BundlePaths {
    pub pkgdatadir: PathBuf,
    pub localedir: PathBuf,
}

pub fn setup_bundle_env() -> Option<BundlePaths> {
    let exe = std::env::current_exe().ok()?;
    let exe_dir = exe.parent()?.to_path_buf();

    let mut comps = exe_dir.components().rev();
    let last = comps.next()?.as_os_str();
    let prev = comps.next()?.as_os_str();

    if last != "MacOS" || prev != "Contents" {
        return None;
    }

    let resources = exe_dir.join("..").join("Resources");
    let xdg_data_dirs = resources.join("share");
    let pixbuf_cache = resources.join("etc").join("loaders.cache");

    // SAFETY: called once at the very start of `run()`, before any threads are spawned and before GTK initialization.
    // The only point at which mutating the process environment is safe in Rust 2024, according to documentation
    unsafe {
        std::env::set_var("XDG_DATA_DIRS", &xdg_data_dirs);
        std::env::set_var("GDK_PIXBUF_MODULE_FILE", &pixbuf_cache);
    }

    Some(BundlePaths {
        pkgdatadir: xdg_data_dirs.join("gitte"),
        localedir: xdg_data_dirs.join("locale"),
    })
}

pub fn bundle_paths() -> (PathBuf, PathBuf) {
    setup_bundle_env()
        .map(|b| (b.pkgdatadir, b.localedir))
        .unwrap_or_else(|| (PathBuf::from(PKGDATADIR), PathBuf::from(LOCALEDIR)))
}
