#include <doctest/doctest.h>

#include "fgc/HelpText.h"

#include <string>

using namespace fgc;

namespace {
std::string join(const std::vector<std::string>& v) {
    std::string s;
    for (const auto& l : v) s += l + "\n";
    return s;
}
}  // namespace

TEST_CASE("helpCatalog is well-formed") {
    const auto& cat = helpCatalog();
    REQUIRE_FALSE(cat.empty());
    for (const auto& sec : cat) {
        CHECK_FALSE(sec.title.empty());
        CHECK_FALSE(sec.entries.empty());
        for (const auto& e : sec.entries) {
            CHECK_FALSE(e.syntax.empty());
            CHECK_FALSE(e.summary.empty());
        }
    }
}

TEST_CASE("renderHelp() with no topic lists every section and entry") {
    std::string out = join(renderHelp(""));
    CHECK(out.find("help <topic>") != std::string::npos);  // the usage hint
    // Each catalog section title and entry syntax should appear.
    for (const auto& sec : helpCatalog()) {
        CHECK(out.find(sec.title) != std::string::npos);
        for (const auto& e : sec.entries)
            CHECK(out.find(e.syntax) != std::string::npos);
    }
    // A couple of the commands.
    CHECK(out.find("gimbal move") != std::string::npos);
    CHECK(out.find("gimbal calib") != std::string::npos);
}

TEST_CASE("renderHelp(<section>) expands that section with detail") {
    std::string out = join(renderHelp("positioning"));
    CHECK(out.find("gimbal move <yaw>,<pitch>") != std::string::npos);
    // Detail lines (example) are only emitted in topic mode.
    CHECK(out.find("gimbal move 30,-10") != std::string::npos);
}

TEST_CASE("renderHelp(<verb>) matches the gimbal commands, case-insensitively") {
    std::string lower = join(renderHelp("gimbal"));
    std::string upper = join(renderHelp("GIMBAL"));
    CHECK(lower.find("gimbal move <yaw>,<pitch>") != std::string::npos);
    CHECK(lower.find("gimbal calib") != std::string::npos);
    CHECK(lower == upper);
}

TEST_CASE("renderHelp(unknown) reports no match") {
    std::string out = join(renderHelp("definitely-not-a-command"));
    CHECK(out.find("No help topic") != std::string::npos);
}
