#include <os/ArgumentParser.h>
#include <os/Directory.h>
#include <os/File.h>
#include <os/FileSystem.h>

Result<void> remove_wrapper(const os::Path& path, bool verbose)
{
    TRY(os::FileSystem::remove(path));
    if (verbose) os::println("removed '%s'", path.name().chars());
    return {};
}

Result<void> remove_tree(const os::Path& path, bool verbose)
{
    auto rc = remove_wrapper(path, verbose);
    if (!rc.has_error()) return {};
    if (rc.error() != ENOTEMPTY) return rc.release_error();

    auto dir = TRY(os::Directory::open(path));

    Vector<String> entries = TRY(dir->list_names(os::Directory::Filter::ParentAndBase));

    for (const auto& entry : entries) { TRY(remove_tree({ dir->fd(), entry.view() }, verbose)); }

    return remove_wrapper(path, verbose);
}

Result<int> luna_main(int argc, char** argv)
{
    StringView path;
    bool recursive;
    bool verbose;

    os::ArgumentParser parser;
    parser.add_description("Remove a path from the file system."_sv);
    parser.add_system_program_info("rm"_sv);
    parser.add_positional_argument(path, "path"_sv, true);
    parser.add_switch_argument(recursive, 'r', "recursive"_sv,
                               "remove a directory recursively (by default, rm removes only empty directories)"_sv);
    parser.add_switch_argument(verbose, 'v', "verbose"_sv, "log every removed file and directory"_sv);
    parser.parse(argc, argv);

    if (!recursive) TRY(remove_wrapper(path, verbose));
    else
        TRY(remove_tree(path, verbose));

    return 0;
}