//
// Syd: rock-solid unikernel
// src/syd-read.rs: Print the canonicalized path name followed by a newline and exit.
//
// Copyright (c) 2024 Ali Polatel <alip@chesswob.org>
//
// SPDX-License-Identifier: GPL-3.0-or-later

use std::{io::Write, os::unix::ffi::OsStrExt, path::Path, process::ExitCode};

use nix::unistd::Pid;
use syd::{err::SydResult, fs::read_link};

// Set global allocator to mimalloc.
#[global_allocator]
static GLOBAL: mimalloc2_rust::GlobalMiMalloc = mimalloc2_rust::GlobalMiMalloc;

fn main() -> SydResult<ExitCode> {
    syd::set_sigpipe_dfl()?;

    // Configure mimalloc.
    syd::configure_mimalloc();

    let mut args = std::env::args();

    match args.nth(1).as_deref() {
        None | Some("-h") => {
            println!("Usage: syd-read path");
            println!("Print the canonicalized path name followed by a newline and exit.");
        }
        Some(value) => {
            let path = Path::new(value);
            let cwd = if path.is_relative() {
                match read_link(Path::new("/proc/self/cwd")) {
                    Ok(cwd) => Some(cwd),
                    Err(error) => {
                        eprintln!("Error reading current working directory: {error}!");
                        return Ok(ExitCode::FAILURE);
                    }
                }
            } else {
                None
            };
            let path = match syd::fs::canonicalize(
                Pid::this(),
                path,
                cwd.as_deref(),
                syd::fs::MissingHandling::Normal,
                true,
                false,
                true,
            ) {
                Ok(path) => path,
                Err(error) => {
                    eprintln!("Error canonicalizing path: {error}!");
                    return Ok(ExitCode::FAILURE);
                }
            };
            let path = path.as_os_str().as_bytes();
            std::io::stdout().write_all(path)?;
            println!();
        }
    }

    Ok(ExitCode::SUCCESS)
}
