//
// Syd: rock-solid application kernel
// src/utils/syd-tty.rs: Print the controlling terminal of the given process.
//
// Copyright (c) 2024, 2025, 2026 Ali Polatel <alip@chesswob.org>
//
// SPDX-License-Identifier: GPL-3.0

use std::{borrow::Cow, process::ExitCode};

use nix::fcntl::{OFlag, AT_FDCWD};
use syd::{
    compat::{openat2, FsType, OpenHow, ResolveFlag},
    path::{XPath, XPathBuf},
    retry::retry_on_eintr,
};

// 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()?;

    let file = match std::env::args_os().nth(1).map(XPathBuf::from) {
        Some(file) if file.is_equal(b"-h") || file.is_equal(b"--help") => {
            help();
            return Ok(ExitCode::SUCCESS);
        }
        Some(file) => Cow::Owned(file),
        None => Cow::Borrowed(XPath::dot()),
    };

    // SAFETY:
    // 1. Do not follow symlinks in any of the path components.
    // 2. Do not follow symlinks in last path component.
    let how = OpenHow::new()
        .flags(OFlag::O_PATH | OFlag::O_CLOEXEC | OFlag::O_NOFOLLOW)
        .resolve(ResolveFlag::RESOLVE_NO_MAGICLINKS | ResolveFlag::RESOLVE_NO_SYMLINKS);
    #[expect(clippy::disallowed_methods)]
    let fstype = retry_on_eintr(|| openat2(AT_FDCWD, file.as_ref(), how)).and_then(FsType::get)?;

    println!("{fstype}");
    Ok(ExitCode::SUCCESS)
}

fn help() {
    println!("Usage: syd-fs [FILE]");
    println!("Print the filesystem type of the given file or current working directory.");
}
