#include <array>
#include <catch2/catch_test_macros.hpp>

#include "fsfw/subsystem/modes/ModeDefinitions.h"

TEST_CASE("Mode Definitions", "[mode]") {
  ModeListEntry entry;

  SECTION("Basic") {
    entry.setMode(HasModesIF::MODE_OFF);
    entry.setSubmode(2);
    CHECK(entry.getMode() == HasModesIF::MODE_OFF);
    CHECK(entry.getSubmode() == 2);
    uint8_t mask;
    CHECK(entry.submodesAllowed(&mask) == false);
  }

  SECTION("Allowed submode mask") {
    entry.allowAllSubmodes();
    uint8_t mask;
    CHECK(entry.submodesAllowed(&mask) == true);
    CHECK(mask == 0xff);
  }

  SECTION("Serialization") {
    std::array<uint8_t, 32> buf{};
    entry.setObject(0x1f2f3f4f);
    entry.setMode(HasModesIF::MODE_ON);
    entry.setSubmode(2);
    entry.enableInheritSubmode();
    entry.enableSubmodeAllowed(0x1f);
    uint8_t* serPtr = buf.data();
    size_t serLen = 0;
    REQUIRE(entry.serialize(&serPtr, &serLen, buf.size(), SerializeIF::Endianness::NETWORK) ==
            returnvalue::OK);
    CHECK(buf[0] == 0x1f);
    CHECK(buf[1] == 0x2f);
    CHECK(buf[2] == 0x3f);
    CHECK(buf[3] == 0x4f);
    CHECK(buf[4] == 0);
    CHECK(buf[5] == 0);
    CHECK(buf[6] == 0);
    CHECK(buf[7] == HasModesIF::MODE_ON);
    CHECK(buf[8] == 2);
    CHECK(buf[9] == (mode::SpecialSubmodeFlags::ALLOWED_MASK | mode::SpecialSubmodeFlags::INHERIT));
    CHECK(buf[10] == 0x1f);
  }
}