#include "bej_dictionary.h"
#include "bej_encoder_core.h"
#include "bej_tree.h"

#include "bej_common_test.hpp"
#include "bej_decoder_json.hpp"
#include "bej_deferred_binding_format.hpp"
#include "bej_encoder_json.hpp"

#include <vector>

#include <gmock/gmock-matchers.h>
#include <gmock/gmock.h>
#include <gtest/gtest.h>

namespace libbej
{

struct BejEncoderTestParams
{
    const std::string testName;
    const BejTestInputFiles inputFiles;
    std::string expectedJson;
    struct RedfishPropertyParent* (*createResource)();
};

void PrintTo(const BejEncoderTestParams& params, std::ostream* os)
{
    *os << params.testName;
}

using BejEncoderTest = testing::TestWithParam<BejEncoderTestParams>;

const BejTestInputFiles dummySimpleTestFiles = {
    .jsonFile = "../test/json/dummysimple.json",
    .schemaDictionaryFile = "../test/dictionaries/dummy_simple_dict.bin",
    .annotationDictionaryFile = "../test/dictionaries/annotation_dict.bin",
    .errorDictionaryFile = "",
    .encodedStreamFile = "../test/encoded/dummy_simple_enc.bin",
};

const BejTestInputFiles driveOemTestFiles = {
    .jsonFile = "../test/json/drive_oem.json",
    .schemaDictionaryFile = "../test/dictionaries/drive_oem_dict.bin",
    .annotationDictionaryFile = "../test/dictionaries/annotation_dict.bin",
    .errorDictionaryFile = "",
    .encodedStreamFile = "../test/encoded/drive_oem_enc.bin",
};

const BejTestInputFiles chassisTestFiles = {
    .jsonFile = "../test/json/chassis.json",
    .schemaDictionaryFile = "../test/dictionaries/chassis_dict.bin",
    .annotationDictionaryFile = "../test/dictionaries/annotation_dict.bin",
    .errorDictionaryFile = "",
    .encodedStreamFile = "../test/encoded/chassis_enc.bin",
};

struct RedfishPropertyParent* createDummyResource()
{
    static struct RedfishPropertyParent root;
    bejTreeInitSet(&root, "DummySimple");

    static struct RedfishPropertyParent annotationSet;
    bejTreeInitSet(&annotationSet, "@Redfish.Settings");

    static struct RedfishPropertyLeafString annotationType;
    bejTreeAddString(&annotationSet, &annotationType, "@odata.type",
                     "#Settings.v1_0_0.Settings");

    bejTreeLinkChildToParent(&root, &annotationSet);

    static struct RedfishPropertyLeafString id;
    bejTreeAddString(&root, &id, "Id", "Dummy ID");

    static struct RedfishPropertyLeafInt intProp;
    bejTreeAddInteger(&root, &intProp, "SampleIntegerProperty", -5);

    static struct RedfishPropertyLeafReal real;
    bejTreeAddReal(&root, &real, "SampleRealProperty", -5576.90001);

    static struct RedfishPropertyLeafNull enProp;
    bejTreeAddNull(&root, &enProp, "SampleEnabledProperty");

    static struct RedfishPropertyParent chArraySet1;
    bejTreeInitSet(&chArraySet1, nullptr);

    static struct RedfishPropertyLeafBool chArraySet1bool;
    bejTreeAddBool(&chArraySet1, &chArraySet1bool, "AnotherBoolean", true);

    static struct RedfishPropertyLeafEnum chArraySet1Ls;
    bejTreeAddEnum(&chArraySet1, &chArraySet1Ls, "LinkStatus", "NoLink");

    static struct RedfishPropertyParent chArraySet2;
    bejTreeInitSet(&chArraySet2, nullptr);

    static struct RedfishPropertyLeafEnum chArraySet2Ls;
    bejTreeAddEnum(&chArraySet2, &chArraySet2Ls, "LinkStatus", "LinkDown");

    static struct RedfishPropertyParent chArray;
    bejTreeInitArray(&chArray, "ChildArrayProperty");

    bejTreeLinkChildToParent(&chArray, &chArraySet1);
    bejTreeLinkChildToParent(&chArray, &chArraySet2);

    bejTreeLinkChildToParent(&root, &chArray);
    return &root;
}

const std::string driveOemJson = R"(
      {
        "@odata.id": "/redfish/v1/drives/1",
        "@odata.type": "#Drive.v1_5_0.Drive",
        "Id": "Drive1",
        "Actions": {
            "#Drive.Reset": {
                "target": "/redfish/v1/drives/1/Actions/Drive.Reset",
                "title": "Reset a Drive",
                "ResetType@Redfish.AllowableValues": [
                        "On",
                        "ForceOff",
                        "ForceRestart",
                        "Nmi",
                        "ForceOn",
                        "PushPowerButton"
                    ]
            }
        },
        "Status@Message.ExtendedInfo": [
            {
                "MessageId": "PredictiveFailure",
                "RelatedProperties": ["FailurePredicted", "MediaType"]
            }
        ],
        "Identifiers": [],
        "Links": {}
    }
)";

struct RedfishPropertyParent* createDriveOem()
{
    static struct RedfishPropertyParent root;
    bejTreeInitSet(&root, "Drive");

    static struct RedfishPropertyLeafString odataId;
    bejTreeAddString(&root, &odataId, "@odata.id", "/redfish/v1/drives/1");

    static struct RedfishPropertyLeafString odataType;
    bejTreeAddString(&root, &odataType, "@odata.type", "#Drive.v1_5_0.Drive");

    static struct RedfishPropertyLeafString id;
    bejTreeAddString(&root, &id, "Id", "Drive1");

    static struct RedfishPropertyParent actions;
    bejTreeInitSet(&actions, "Actions");

    static struct RedfishPropertyParent drRst;
    bejTreeInitSet(&drRst, "#Drive.Reset");

    static struct RedfishPropertyLeafString drRstTarget;
    bejTreeAddString(&drRst, &drRstTarget, "target",
                     "/redfish/v1/drives/1/Actions/Drive.Reset");

    static struct RedfishPropertyLeafString drRstTitle;
    bejTreeAddString(&drRst, &drRstTitle, "title", "Reset a Drive");

    static struct RedfishPropertyParent drRstType;
    bejTreeInitPropertyAnnotated(&drRstType, "ResetType");

    static struct RedfishPropertyParent drRstTypeAllowable;
    bejTreeInitArray(&drRstTypeAllowable, "@Redfish.AllowableValues");

    static struct RedfishPropertyLeafString drRstTypeAllowableS1;
    bejTreeAddString(&drRstTypeAllowable, &drRstTypeAllowableS1, "", "On");

    static struct RedfishPropertyLeafString drRstTypeAllowableS2;
    bejTreeAddString(&drRstTypeAllowable, &drRstTypeAllowableS2, "",
                     "ForceOff");

    static struct RedfishPropertyLeafString drRstTypeAllowableS3;
    bejTreeAddString(&drRstTypeAllowable, &drRstTypeAllowableS3, "",
                     "ForceRestart");

    static struct RedfishPropertyLeafString drRstTypeAllowableS4;
    bejTreeAddString(&drRstTypeAllowable, &drRstTypeAllowableS4, "", "Nmi");

    static struct RedfishPropertyLeafString drRstTypeAllowableS5;
    bejTreeAddString(&drRstTypeAllowable, &drRstTypeAllowableS5, "", "ForceOn");

    static struct RedfishPropertyLeafString drRstTypeAllowableS6;
    bejTreeAddString(&drRstTypeAllowable, &drRstTypeAllowableS6, "",
                     "PushPowerButton");

    bejTreeLinkChildToParent(&drRstType, &drRstTypeAllowable);
    bejTreeLinkChildToParent(&drRst, &drRstType);
    bejTreeLinkChildToParent(&actions, &drRst);
    bejTreeLinkChildToParent(&root, &actions);

    static struct RedfishPropertyParent statusAnt;
    bejTreeInitPropertyAnnotated(&statusAnt, "Status");

    static struct RedfishPropertyParent statusAntMsgExtInfo;
    bejTreeInitArray(&statusAntMsgExtInfo, "@Message.ExtendedInfo");

    static struct RedfishPropertyParent statusAntMsgExtInfoSet1;
    bejTreeInitSet(&statusAntMsgExtInfoSet1, nullptr);

    static struct RedfishPropertyLeafString statusAntMsgExtInfoSet1P1;
    bejTreeAddString(&statusAntMsgExtInfoSet1, &statusAntMsgExtInfoSet1P1,
                     "MessageId", "PredictiveFailure");

    static struct RedfishPropertyParent statusAntMsgExtInfoSet1P2;
    bejTreeInitArray(&statusAntMsgExtInfoSet1P2, "RelatedProperties");
    bejTreeLinkChildToParent(&statusAntMsgExtInfoSet1,
                             &statusAntMsgExtInfoSet1P2);

    static struct RedfishPropertyLeafString statusAntMsgExtInfoSet1P2Ele1;
    bejTreeAddString(&statusAntMsgExtInfoSet1P2, &statusAntMsgExtInfoSet1P2Ele1,
                     "", "FailurePredicted");

    static struct RedfishPropertyLeafString statusAntMsgExtInfoSet1P2Ele2;
    bejTreeAddString(&statusAntMsgExtInfoSet1P2, &statusAntMsgExtInfoSet1P2Ele2,
                     "", "MediaType");

    bejTreeLinkChildToParent(&statusAntMsgExtInfo, &statusAntMsgExtInfoSet1);
    bejTreeLinkChildToParent(&statusAnt, &statusAntMsgExtInfo);
    bejTreeLinkChildToParent(&root, &statusAnt);

    static struct RedfishPropertyParent identifiers;
    bejTreeInitArray(&identifiers, "Identifiers");
    bejTreeLinkChildToParent(&root, &identifiers);

    static struct RedfishPropertyParent links;
    bejTreeInitSet(&links, "Links");
    bejTreeLinkChildToParent(&root, &links);

    return &root;
}

/**
 * @brief Storage for an array of links with an annotated odata.count.
 *
 * This doesn't contain storage for the link itself.
 *
 * Eg:
 * "Contains": [],
 * "Contains@odata.count": 0,
 */
struct RedfishArrayOfLinksJson
{
    struct RedfishPropertyParent array;
    struct RedfishPropertyParent annotatedProperty;
    struct RedfishPropertyLeafInt count;
};

/**
 * @brief Storage for a single odata.id link inside a JSON "Set" object.
 *
 * Eg: FieldName: {
 *   "@odata.id": "/redfish/v1/Chassis/Something"
 * }
 */
struct RedfishLinkJson
{
    struct RedfishPropertyParent set;
    struct RedfishPropertyLeafString odataId;
};

void addLinkToTree(struct RedfishPropertyParent* parent,
                   struct RedfishPropertyParent* linkSet,
                   const char* linkSetLabel,
                   struct RedfishPropertyLeafString* odataId,
                   const char* linkValue)
{
    bejTreeInitSet(linkSet, linkSetLabel);
    bejTreeAddString(linkSet, odataId, "@odata.id", linkValue);
    bejTreeLinkChildToParent(parent, linkSet);
}

void redfishCreateArrayOfLinksJson(
    struct RedfishPropertyParent* parent, const char* arrayName, int linkCount,
    const char* const links[], struct RedfishArrayOfLinksJson* linksInfo,
    struct RedfishLinkJson* linkJsonArray)
{
    bejTreeInitArray(&linksInfo->array, arrayName);
    bejTreeLinkChildToParent(parent, &linksInfo->array);

    bejTreeInitPropertyAnnotated(&linksInfo->annotatedProperty, arrayName);
    bejTreeAddInteger(&linksInfo->annotatedProperty, &linksInfo->count,
                      "@odata.count", linkCount);
    bejTreeLinkChildToParent(parent, &linksInfo->annotatedProperty);

    for (int i = 0; i < linkCount; ++i)
    {
        addLinkToTree(&linksInfo->array, &linkJsonArray[i].set, nullptr,
                      &linkJsonArray[i].odataId, links[i]);
    }
}

struct RedfishPropertyParent* createChassisResource()
{
    constexpr int containsLinkCount = 2;
    const char* contains[containsLinkCount] = {"/redfish/v1/Chassis/Disk_0",
                                               "/redfish/v1/Chassis/Disk_1"};
    const char* storage[1] = {"/redfish/v1/Systems/system/Storage/SATA"};
    const char* drives[1] = {"/redfish/v1/Chassis/SomeChassis/Drives/SATA_0"};
    static struct RedfishPropertyParent root;
    static struct RedfishPropertyLeafString odataId;
    static struct RedfishPropertyParent links;
    static struct RedfishPropertyParent computerSystemsArray;
    static struct RedfishPropertyParent computerSystemsLinkSet;
    static struct RedfishPropertyLeafString computerSystemsLinkOdataId;
    static struct RedfishPropertyParent containedBySet;
    static struct RedfishPropertyLeafString containedByOdataId;
    static struct RedfishArrayOfLinksJson containsArray;
    static struct RedfishLinkJson containsLinks[containsLinkCount];
    static struct RedfishArrayOfLinksJson storageArray;
    static struct RedfishLinkJson storageLink;
    static struct RedfishArrayOfLinksJson drives_array;
    static struct RedfishLinkJson drive_link;

    bejTreeInitSet(&root, "Chassis");
    bejTreeAddString(&root, &odataId, "@odata.id",
                     "/redfish/v1/Chassis/SomeChassis");

    bejTreeInitSet(&links, "Links");
    bejTreeLinkChildToParent(&root, &links);

    bejTreeInitArray(&computerSystemsArray, "ComputerSystems");
    bejTreeLinkChildToParent(&links, &computerSystemsArray);

    addLinkToTree(&computerSystemsArray, &computerSystemsLinkSet, "",
                  &computerSystemsLinkOdataId, "/redfish/v1/Systems/system");

    addLinkToTree(&links, &containedBySet, "ContainedBy", &containedByOdataId,
                  "/redfish/v1/Chassis/SomeOtherChassis");

    redfishCreateArrayOfLinksJson(&links, "Contains", containsLinkCount,
                                  contains, &containsArray, containsLinks);

    redfishCreateArrayOfLinksJson(&links, "Storage", /*linkCount=*/1, storage,
                                  &storageArray, &storageLink);

    redfishCreateArrayOfLinksJson(&links, "Drives", /*linkCount=*/1, drives,
                                  &drives_array, &drive_link);

    return &root;
}

TEST_P(BejEncoderTest, Encode)
{
    const BejEncoderTestParams& test_case = GetParam();
    auto inputsOrErr = loadInputs(test_case.inputFiles);
    EXPECT_TRUE(inputsOrErr);

    BejDictionaries dictionaries = {
        .schemaDictionary = inputsOrErr->schemaDictionary,
        .schemaDictionarySize = inputsOrErr->schemaDictionarySize,
        .annotationDictionary = inputsOrErr->annotationDictionary,
        .annotationDictionarySize = inputsOrErr->annotationDictionarySize,
        .errorDictionary = inputsOrErr->errorDictionary,
        .errorDictionarySize = inputsOrErr->errorDictionarySize,
    };

    std::vector<uint8_t> outputBuffer;
    struct BejEncoderOutputHandler output = {
        .handlerContext = &outputBuffer,
        .recvOutput = &getBejEncodedBuffer,
    };

    std::vector<void*> pointerStack;
    struct BejPointerStackCallback stackCallbacks = {
        .stackContext = &pointerStack,
        .stackEmpty = stackEmpty,
        .stackPeek = stackPeek,
        .stackPop = stackPop,
        .stackPush = stackPush,
        .deleteStack = nullptr,
    };

    bejEncode(&dictionaries, BEJ_DICTIONARY_START_AT_HEAD, bejMajorSchemaClass,
              test_case.createResource(), &output, &stackCallbacks);

    BejDecoderJson decoder;
    EXPECT_THAT(decoder.decode(dictionaries, std::span(outputBuffer)), 0);
    std::string decoded = decoder.getOutput();
    nlohmann::json jsonDecoded = nlohmann::json::parse(decoded);

    if (!test_case.expectedJson.empty())
    {
        inputsOrErr->expectedJson =
            nlohmann::json::parse(test_case.expectedJson);
    }
    EXPECT_TRUE(jsonDecoded.dump() == inputsOrErr->expectedJson.dump());
}

TEST_P(BejEncoderTest, EncodeWrapper)
{
    const BejEncoderTestParams& test_case = GetParam();
    auto inputsOrErr = loadInputs(test_case.inputFiles);
    EXPECT_TRUE(inputsOrErr);

    BejDictionaries dictionaries = {
        .schemaDictionary = inputsOrErr->schemaDictionary,
        .schemaDictionarySize = inputsOrErr->schemaDictionarySize,
        .annotationDictionary = inputsOrErr->annotationDictionary,
        .annotationDictionarySize = inputsOrErr->annotationDictionarySize,
        .errorDictionary = inputsOrErr->errorDictionary,
        .errorDictionarySize = inputsOrErr->errorDictionarySize,
    };

    libbej::BejEncoderJson encoder;
    encoder.encode(&dictionaries, bejMajorSchemaClass,
                   test_case.createResource());

    std::vector<uint8_t> outputBuffer = encoder.getOutput();
    BejDecoderJson decoder;
    EXPECT_THAT(decoder.decode(dictionaries, std::span(outputBuffer)), 0);
    std::string decoded = decoder.getOutput();
    nlohmann::json jsonDecoded = nlohmann::json::parse(decoded);

    if (!test_case.expectedJson.empty())
    {
        inputsOrErr->expectedJson =
            nlohmann::json::parse(test_case.expectedJson);
    }
    EXPECT_TRUE(jsonDecoded.dump() == inputsOrErr->expectedJson.dump());

    // Try using the same encoder object again to ensure that the same object
    // does the encoding correctly
    encoder.encode(&dictionaries, bejMajorSchemaClass,
                   test_case.createResource());

    outputBuffer = encoder.getOutput();

    EXPECT_THAT(decoder.decode(dictionaries, std::span(outputBuffer)), 0);
    decoded = decoder.getOutput();
    jsonDecoded = nlohmann::json::parse(decoded);

    if (!test_case.expectedJson.empty())
    {
        inputsOrErr->expectedJson =
            nlohmann::json::parse(test_case.expectedJson);
    }
    EXPECT_TRUE(jsonDecoded.dump() == inputsOrErr->expectedJson.dump());
}

TEST(BejEncoderDeferredBindingTest, DeferredBindingEncodeDecode)
{
    auto inputsOrErr = loadInputs(driveOemTestFiles);
    ASSERT_TRUE(inputsOrErr);

    BejDictionaries dictionaries = {
        .schemaDictionary = inputsOrErr->schemaDictionary,
        .schemaDictionarySize = inputsOrErr->schemaDictionarySize,
        .annotationDictionary = inputsOrErr->annotationDictionary,
        .annotationDictionarySize = inputsOrErr->annotationDictionarySize,
        .errorDictionary = inputsOrErr->errorDictionary,
        .errorDictionarySize = inputsOrErr->errorDictionarySize,
    };

    // We will use DriveOEM which has `@odata.id`: `/redfish/v1/drives/1`.
    // Let's create a reverse mapping config where resourceId = 30 points to
    // this URI.
    BejDeferredBindingMap bindings;
    bindings[bejBinding::resourceLink(30)] = "/redfish/v1/drives/1";
    bindings[bejBinding::instanceId(30)] = "Drive1";
    // Target action mapping simulation
    bindings[bejBinding::action(30, 1)] =
        "/redfish/v1/drives/1/Actions/Drive.Reset";

    libbej::BejEncoderJson encoder;
    struct RedfishPropertyParent* root = createDriveOem();

    // Encode with binding map
    encoder.encode(&dictionaries, bejMajorSchemaClass, root, bindings);

    std::vector<uint8_t> outputBuffer = encoder.getOutput();

    // Decode with binding map
    libbej::BejDecoderJson decoder;
    EXPECT_THAT(decoder.decode(dictionaries, std::span(outputBuffer), bindings),
                0);
    std::string decoded = decoder.getOutput();
    nlohmann::json jsonDecoded = nlohmann::json::parse(decoded);

    // After decode, the json should perfectly match the input strings
    // because `%L30`, `%I30` should be resolved back to their original strings.
    std::string odataId = jsonDecoded["@odata.id"].get<std::string>();
    EXPECT_EQ(odataId, "/redfish/v1/drives/1");

    std::string id = jsonDecoded["Id"].get<std::string>();
    EXPECT_EQ(id, "Drive1");

    // Action URI
    std::string actionTarget =
        jsonDecoded["Actions"]["#Drive.Reset"]["target"].get<std::string>();
    EXPECT_EQ(actionTarget, "/redfish/v1/drives/1/Actions/Drive.Reset");
}

TEST(BejEncoderDeferredBindingTest, EncodeDoesNotMutateInputTree)
{
    auto inputsOrErr = loadInputs(driveOemTestFiles);
    ASSERT_TRUE(inputsOrErr);

    BejDictionaries dictionaries = {
        .schemaDictionary = inputsOrErr->schemaDictionary,
        .schemaDictionarySize = inputsOrErr->schemaDictionarySize,
        .annotationDictionary = inputsOrErr->annotationDictionary,
        .annotationDictionarySize = inputsOrErr->annotationDictionarySize,
        .errorDictionary = inputsOrErr->errorDictionary,
        .errorDictionarySize = inputsOrErr->errorDictionarySize,
    };

    BejDeferredBindingMap bindings;
    bindings[bejBinding::resourceLink(30)] = "/redfish/v1/drives/1";
    bindings[bejBinding::instanceId(30)] = "Drive1";
    bindings[bejBinding::action(30, 1)] =
        "/redfish/v1/drives/1/Actions/Drive.Reset";

    // encode() temporarily rewrites matching leaf values to placeholders, then
    // must restore them (value pointers and deferred-binding flags) before
    // returning.
    struct RedfishPropertyParent* root = createDriveOem();
    libbej::BejEncoderJson boundEncoder;
    boundEncoder.encode(&dictionaries, bejMajorSchemaClass, root, bindings);

    // Re-encoding the same tree WITHOUT bindings must reproduce a clean encode
    // of an untouched tree; any residual placeholder or flag would differ.
    libbej::BejEncoderJson reuseEncoder;
    reuseEncoder.encode(&dictionaries, bejMajorSchemaClass, root);
    std::vector<uint8_t> afterRestore = reuseEncoder.getOutput();

    libbej::BejEncoderJson referenceEncoder;
    referenceEncoder.encode(&dictionaries, bejMajorSchemaClass,
                            createDriveOem());
    std::vector<uint8_t> reference = referenceEncoder.getOutput();

    EXPECT_EQ(afterRestore, reference);
}

TEST(BejEncoderDeferredBindingTest, UnresolvedPlaceholdersBecomeInvalidForm)
{
    auto inputsOrErr = loadInputs(driveOemTestFiles);
    ASSERT_TRUE(inputsOrErr);

    BejDictionaries dictionaries = {
        .schemaDictionary = inputsOrErr->schemaDictionary,
        .schemaDictionarySize = inputsOrErr->schemaDictionarySize,
        .annotationDictionary = inputsOrErr->annotationDictionary,
        .annotationDictionarySize = inputsOrErr->annotationDictionarySize,
        .errorDictionary = inputsOrErr->errorDictionary,
        .errorDictionarySize = inputsOrErr->errorDictionarySize,
    };

    BejDeferredBindingMap bindings;
    bindings[bejBinding::resourceLink(30)] = "/redfish/v1/drives/1";
    bindings[bejBinding::instanceId(30)] = "Drive1";
    bindings[bejBinding::action(30, 1)] =
        "/redfish/v1/drives/1/Actions/Drive.Reset";

    libbej::BejEncoderJson encoder;
    encoder.encode(&dictionaries, bejMajorSchemaClass, createDriveOem(),
                   bindings);
    std::vector<uint8_t> outputBuffer = encoder.getOutput();

    // Decode with a non-empty map that does NOT contain resource 30: resolution
    // is enabled, so each unresolved placeholder must become its DSP0218
    // Table 42 invalid form rather than being left raw.
    BejDeferredBindingMap unrelated;
    unrelated[bejBinding::resourceLink(99)] = "/redfish/v1/unrelated";

    libbej::BejDecoderJson decoder;
    EXPECT_THAT(
        decoder.decode(dictionaries, std::span(outputBuffer), unrelated), 0);
    nlohmann::json jsonDecoded = nlohmann::json::parse(decoder.getOutput());

    EXPECT_EQ(jsonDecoded["@odata.id"].get<std::string>(), "/invalid.PDR30");
    EXPECT_EQ(jsonDecoded["Id"].get<std::string>(), "invalid");
    EXPECT_EQ(
        jsonDecoded["Actions"]["#Drive.Reset"]["target"].get<std::string>(),
        "/invalid.30.1");
}

TEST(BejEncoderDeferredBindingTest, DisabledModeLeavesPlaceholdersRaw)
{
    auto inputsOrErr = loadInputs(driveOemTestFiles);
    ASSERT_TRUE(inputsOrErr);

    BejDictionaries dictionaries = {
        .schemaDictionary = inputsOrErr->schemaDictionary,
        .schemaDictionarySize = inputsOrErr->schemaDictionarySize,
        .annotationDictionary = inputsOrErr->annotationDictionary,
        .annotationDictionarySize = inputsOrErr->annotationDictionarySize,
        .errorDictionary = inputsOrErr->errorDictionary,
        .errorDictionarySize = inputsOrErr->errorDictionarySize,
    };

    BejDeferredBindingMap bindings;
    bindings[bejBinding::resourceLink(30)] = "/redfish/v1/drives/1";
    bindings[bejBinding::instanceId(30)] = "Drive1";
    bindings[bejBinding::action(30, 1)] =
        "/redfish/v1/drives/1/Actions/Drive.Reset";

    libbej::BejEncoderJson encoder;
    encoder.encode(&dictionaries, bejMajorSchemaClass, createDriveOem(),
                   bindings);
    std::vector<uint8_t> outputBuffer = encoder.getOutput();

    // Decode without a map (the default): resolution is disabled, so every
    // placeholder is preserved verbatim instead of being substituted.
    libbej::BejDecoderJson decoder;
    EXPECT_THAT(decoder.decode(dictionaries, std::span(outputBuffer)), 0);
    nlohmann::json jsonDecoded = nlohmann::json::parse(decoder.getOutput());

    EXPECT_EQ(jsonDecoded["@odata.id"].get<std::string>(), "%L30");
    EXPECT_EQ(jsonDecoded["Id"].get<std::string>(), "%I30");
    EXPECT_EQ(
        jsonDecoded["Actions"]["#Drive.Reset"]["target"].get<std::string>(),
        "%T30.1");
}

TEST(BejEncoderDeferredBindingTest, IdlessMarkerRoundTrips)
{
    auto inputsOrErr = loadInputs(driveOemTestFiles);
    ASSERT_TRUE(inputsOrErr);

    BejDictionaries dictionaries = {
        .schemaDictionary = inputsOrErr->schemaDictionary,
        .schemaDictionarySize = inputsOrErr->schemaDictionarySize,
        .annotationDictionary = inputsOrErr->annotationDictionary,
        .annotationDictionarySize = inputsOrErr->annotationDictionarySize,
        .errorDictionary = inputsOrErr->errorDictionary,
        .errorDictionarySize = inputsOrErr->errorDictionarySize,
    };

    // Map only the id-less %C token to the DriveOEM @odata.id value, so the
    // encoder rewrites that leaf to "%C". Exercises a marker carrying no
    // resource id end to end.
    BejDeferredBindingMap bindings;
    bindings[bejBinding::chassis()] = "/redfish/v1/drives/1";

    libbej::BejEncoderJson encoder;
    encoder.encode(&dictionaries, bejMajorSchemaClass, createDriveOem(),
                   bindings);
    std::vector<uint8_t> outputBuffer = encoder.getOutput();

    // Enabled: %C resolves back to the bound value.
    libbej::BejDecoderJson decoder;
    EXPECT_THAT(decoder.decode(dictionaries, std::span(outputBuffer), bindings),
                0);
    nlohmann::json bound = nlohmann::json::parse(decoder.getOutput());
    EXPECT_EQ(bound["@odata.id"].get<std::string>(), "/redfish/v1/drives/1");

    // Disabled: the id-less placeholder is preserved raw as "%C".
    libbej::BejDecoderJson rawDecoder;
    EXPECT_THAT(rawDecoder.decode(dictionaries, std::span(outputBuffer)), 0);
    nlohmann::json raw = nlohmann::json::parse(rawDecoder.getOutput());
    EXPECT_EQ(raw["@odata.id"].get<std::string>(), "%C");
}

TEST(BejEncoderDeferredBindingTest, SystemMarkerRoundTrips)
{
    auto inputsOrErr = loadInputs(driveOemTestFiles);
    ASSERT_TRUE(inputsOrErr);

    BejDictionaries dictionaries = {
        .schemaDictionary = inputsOrErr->schemaDictionary,
        .schemaDictionarySize = inputsOrErr->schemaDictionarySize,
        .annotationDictionary = inputsOrErr->annotationDictionary,
        .annotationDictionarySize = inputsOrErr->annotationDictionarySize,
        .errorDictionary = inputsOrErr->errorDictionary,
        .errorDictionarySize = inputsOrErr->errorDictionarySize,
    };

    // Map only the id-less %S token to the DriveOEM @odata.id value, so the
    // encoder rewrites that leaf to "%S".
    BejDeferredBindingMap bindings;
    bindings[bejBinding::system()] = "/redfish/v1/drives/1";

    libbej::BejEncoderJson encoder;
    encoder.encode(&dictionaries, bejMajorSchemaClass, createDriveOem(),
                   bindings);
    std::vector<uint8_t> outputBuffer = encoder.getOutput();

    // Enabled: %S resolves back to the bound value.
    libbej::BejDecoderJson decoder;
    EXPECT_THAT(decoder.decode(dictionaries, std::span(outputBuffer), bindings),
                0);
    nlohmann::json bound = nlohmann::json::parse(decoder.getOutput());
    EXPECT_EQ(bound["@odata.id"].get<std::string>(), "/redfish/v1/drives/1");

    // Disabled: the id-less placeholder is preserved raw as "%S".
    libbej::BejDecoderJson rawDecoder;
    EXPECT_THAT(rawDecoder.decode(dictionaries, std::span(outputBuffer)), 0);
    nlohmann::json raw = nlohmann::json::parse(rawDecoder.getOutput());
    EXPECT_EQ(raw["@odata.id"].get<std::string>(), "%S");
}

/**
 * TODO: Add more test cases.
 */

INSTANTIATE_TEST_SUITE_P(
    , BejEncoderTest,
    testing::ValuesIn<BejEncoderTestParams>({
        {"DriveOEM", driveOemTestFiles, driveOemJson, &createDriveOem},
        {"DummySimple", dummySimpleTestFiles, "", &createDummyResource},
        {"Chassis", chassisTestFiles, "", &createChassisResource},
    }),
    [](const testing::TestParamInfo<BejEncoderTest::ParamType>& info) {
        return info.param.testName;
    });

} // namespace libbej
