#include "cli/cli.hpp"

#include <cassert>
#include <cctype>
#include <cerrno>
#include <cstdlib>
#include <cstring>
#include <expected>
#include <format>
#include <print>
#include <span>
#include <string_view>

using namespace std::string_view_literals;

void cli::print_usage() {
    std::println("Usage: doniv-cli [-P process_name | -p process_id] -L library_path");
    return;
}
std::string_view cli::cli_args_parse_err_str(cli_args_parse_err err) {
    switch (err) {
    case cli_args_parse_err::invalid_argument:
        return "Invalid command line arguments"sv;
    case cli_args_parse_err::not_enough_args:
        return "Not enough command line parameters"sv;
    default:
        return ""sv;
    }
}

std::expected<cli, cli_args_parse_err> cli::try_construct(int argc, char** argv) {
    if (argc < 1) {
        return std::unexpected(cli_args_parse_err::not_enough_args);
    }

    const std::span<char*> cli_args(argv, argc);
    int                    root_path_arg_idx  = 0;
    int                    prefer_x11_arg_idx = 0;

    for (int i = 0; i < cli_args.size(); ++i) {
        const auto& arg      = cli_args[i];
        const int   next_idx = (i + 1);

        if (std::strcmp(arg, "-root") == 0) {
            if (next_idx < cli_args.size()) {
                root_path_arg_idx = next_idx;
            }
        } else if (std::strcmp(arg, "-x11") == 0) {
            if (next_idx <= cli_args.size()) {
                prefer_x11_arg_idx = i;
            }
        }
    }

    std::filesystem::path root_path;
    bool                  prefer_x11 = false;

    if (root_path_arg_idx) {
        const auto root_path_cstr = cli_args[root_path_arg_idx];
        root_path                 = root_path_cstr;
    }

    prefer_x11 = prefer_x11_arg_idx;

    return cli {root_path, prefer_x11};
}
