#include <os/ArgumentParser.h>
#include <stdio.h>
#include <sys/utsname.h>

#define OPERATING_SYSTEM "Luna"

void print_sequenced(const char* string)
{
    static bool first { true };
    if (!first) { putchar(' '); }
    first = false;
    fputs(string, stdout);
}

Result<int> luna_main(int argc, char** argv)
{
    bool all { false };
    bool kernel_name { false };
    bool node_name { false };
    bool kernel_release { false };
    bool kernel_version { false };
    bool machine { false };
    bool operating_system { false };

    os::ArgumentParser parser;
    parser.add_description("Print system information. If given no options, defaults to -s."_sv);
    parser.add_system_program_info("uname"_sv);
    parser.add_switch_argument(all, 'a', "all"_sv, "print all information"_sv);
    parser.add_switch_argument(kernel_name, 's', "kernel-name"_sv, "print the kernel name"_sv);
    parser.add_switch_argument(node_name, 'n', "nodename"_sv, "print the network hostname"_sv);
    parser.add_switch_argument(kernel_release, 'r', "kernel-release"_sv, "print the kernel release"_sv);
    parser.add_switch_argument(kernel_version, 'v', "kernel-version"_sv, "print the kernel version"_sv);
    parser.add_switch_argument(machine, 'm', "machine"_sv, "print the machine name"_sv);
    parser.add_switch_argument(operating_system, 'o', "operating-system"_sv, "print the operating system"_sv);
    parser.parse(argc, argv);

    // If no options are given, default is -s.
    if (!all && !kernel_name && !node_name && !kernel_release && !kernel_version && !machine && !operating_system)
        kernel_name = true;

    if (all) kernel_name = node_name = kernel_release = kernel_version = machine = operating_system = true;

    struct utsname info;
    if (uname(&info) < 0)
    {
        perror("uname");
        return 1;
    }

    if (kernel_name) print_sequenced(info.sysname);
    if (node_name) print_sequenced(info.nodename);
    if (kernel_release) print_sequenced(info.release);
    if (kernel_version) print_sequenced(info.version);
    if (machine) print_sequenced(info.machine);
    if (operating_system) print_sequenced(OPERATING_SYSTEM);

    putchar('\n');

    return 0;
}