//
// Syd: rock-solid application kernel
// src/utils/syd-emacs.rs: Syd's secure Emacs wrapper
//
// Copyright (c) 2024, 2025, 2026 Ali Polatel <alip@chesswob.org>
//
// SPDX-License-Identifier: GPL-3.0

use std::{
    os::{fd::AsRawFd, unix::process::CommandExt},
    process::Command,
};

use nix::{fcntl::OFlag, sys::stat::Mode, unistd::Uid};

// Set global allocator to GrapheneOS allocator.
#[cfg(all(
    not(coverage),
    not(feature = "prof"),
    not(target_os = "android"),
    not(target_arch = "riscv64"),
    target_page_size_4k,
    target_pointer_width = "64"
))]
#[global_allocator]
static GLOBAL: hardened_malloc::HardenedMalloc = hardened_malloc::HardenedMalloc;

// Set global allocator to tcmalloc if profiling is enabled.
#[cfg(feature = "prof")]
#[global_allocator]
static GLOBAL: tcmalloc::TCMalloc = tcmalloc::TCMalloc;

syd::main! {
    syd::set_sigpipe_dfl()?;

    // Determine HOME directory.
    let uid = Uid::current();
    let name = syd::get_user_name(uid);
    let home = syd::get_user_home(&name);
    let conf = home.join(b".emacs.d/init.syd-3");

    // Prepare command.
    let mut cmd = Command::new("syd");

    // Set up logging.
    let mut buf = itoa::Buffer::new();
    let logf = home.join(b".emacs.d/syd.log");
    #[expect(clippy::disallowed_methods)]
    let file = nix::fcntl::open(
        &logf,
        OFlag::O_CREAT | OFlag::O_APPEND,
        Mode::from_bits_truncate(0o600),
    )?;
    cmd.env("SYD_LOG_FD", buf.format(file.as_raw_fd()));

    // Set up arguments.
    let argv: Vec<String> = std::env::args().skip(1).collect();
    if conf.exists(true) {
        cmd.arg("-P");
        cmd.arg(conf);
    } else {
        cmd.arg("-plib");
    }
    cmd.args(["--", "emacs", "--load=/dev/syd.el"]);
    cmd.args(&argv);

    // Execute Emacs under Syd!
    Err(cmd.exec().into())
}
