#include "libpldmresponder/bios_enum_attribute.hpp"
#include "mocked_bios.hpp"
#include "mocked_utils.hpp"

#include <nlohmann/json.hpp>

#include <memory>

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

using ::testing::_;
using ::testing::ElementsAreArray;
using ::testing::Return;
using ::testing::StrEq;
using ::testing::Throw;

class TestBIOSEnumAttribute : public ::testing::Test
{
  public:
    const auto& getPossibleValues(const BIOSEnumAttribute& attribute)
    {
        return attribute.possibleValues;
    }

    const auto& getDefaultValue(const BIOSEnumAttribute& attribute)
    {
        return attribute.defaultValue;
    }
};

TEST_F(TestBIOSEnumAttribute, CtorTest)
{
    auto jsonEnumReadOnly = R"({
         "attribute_name" : "CodeUpdatePolicy",
         "possible_values" : [ "Concurrent", "Disruptive" ],
         "default_values" : [ "Concurrent" ],
         "readOnly" : true,
         "helpText" : "HelpText",
         "displayName" : "DisplayName"
      })"_json;

    BIOSEnumAttribute enumReadOnly{jsonEnumReadOnly, nullptr};
    EXPECT_EQ(enumReadOnly.name, "CodeUpdatePolicy");
    EXPECT_TRUE(enumReadOnly.readOnly);
    EXPECT_THAT(getPossibleValues(enumReadOnly),
                ElementsAreArray({"Concurrent", "Disruptive"}));
    EXPECT_EQ(getDefaultValue(enumReadOnly), "Concurrent");

    auto jsonEnumReadOnlyError = R"({
         "attribute_name" : "CodeUpdatePolicy",
         "possible_value" : [ "Concurrent", "Disruptive" ],
         "default_values" : [ "Concurrent" ],
         "readOnly" : true,
         "helpText" : "HelpText",
         "displayName" : "DisplayName"
      })"_json; // possible_value -> possible_values
    EXPECT_THROW((BIOSEnumAttribute{jsonEnumReadOnlyError, nullptr}),
                 Json::exception);

    auto jsonEnumReadWrite = R"({
         "attribute_name" : "FWBootSide",
         "possible_values" : [ "Perm", "Temp" ],
         "default_values" : [ "Perm" ],
         "readOnly" : false,
         "helpText" : "HelpText",
         "displayName" : "DisplayName",
         "dbus":
            {
               "object_path" : "/xyz/abc/def",
               "interface" : "xyz.openbmc.FWBoot.Side",
               "property_name" : "Side",
               "property_type" : "bool",
               "property_values" : [true, false]
            }
      })"_json;

    BIOSEnumAttribute enumReadWrite{jsonEnumReadWrite, nullptr};
    EXPECT_EQ(enumReadWrite.name, "FWBootSide");
    EXPECT_TRUE(!enumReadWrite.readOnly);
}

TEST_F(TestBIOSEnumAttribute, ConstructEntry)
{
    MockBIOSStringTable biosStringTable;
    MockdBusHandler dbusHandler;

    auto jsonEnumReadOnly = R"({
         "attribute_name" : "CodeUpdatePolicy",
         "possible_values" : [ "Concurrent", "Disruptive" ],
         "default_values" : [ "Disruptive" ],
         "readOnly" : true,
         "helpText" : "HelpText",
         "displayName" : "DisplayName"
      })"_json;

    std::vector<uint8_t> expectedAttrEntry{
        0,    0, /* attr handle */
        0x80,    /* attr type enum read-only*/
        4,    0, /* attr name handle */
        2,       /* number of possible value */
        2,    0, /* possible value handle */
        3,    0, /* possible value handle */
        1,       /* number of default value */
        1        /* defaut value string handle index */
    };

    std::vector<uint8_t> expectedAttrValueEntry{
        0, 0, /* attr handle */
        0x80, /* attr type enum read-only*/
        1,    /* number of current value */
        1     /* current value string handle index */
    };

    BIOSEnumAttribute enumReadOnly{jsonEnumReadOnly, nullptr};

    ON_CALL(biosStringTable, findHandle(StrEq("Concurrent")))
        .WillByDefault(Return(2));
    ON_CALL(biosStringTable, findHandle(StrEq("Disruptive")))
        .WillByDefault(Return(3));
    ON_CALL(biosStringTable, findHandle(StrEq("CodeUpdatePolicy")))
        .WillByDefault(Return(4));

    checkConstructEntry(enumReadOnly, biosStringTable, expectedAttrEntry,
                        expectedAttrValueEntry);

    auto jsonEnumReadWrite = R"({
         "attribute_name" : "CodeUpdatePolicy",
         "possible_values" : [ "Concurrent", "Disruptive" ],
         "default_values" : [ "Disruptive" ],
         "readOnly" : false,
         "helpText" : "HelpText",
         "displayName" : "DisplayName",
         "dbus":
            {
               "object_path" : "/xyz/abc/def",
               "interface" : "xyz.openbmc.abc.def",
               "property_name" : "Policy",
               "property_type" : "bool",
               "property_values" : [true, false]
          }
      })"_json;

    BIOSEnumAttribute enumReadWrite{jsonEnumReadWrite, &dbusHandler};

    EXPECT_CALL(dbusHandler,
                getDbusPropertyVariant(StrEq("/xyz/abc/def"), StrEq("Policy"),
                                       StrEq("xyz.openbmc.abc.def")))
        .WillOnce(Throw(std::exception()));

    /* Set expected attr type to read-write */
    expectedAttrEntry[2] = PLDM_BIOS_ENUMERATION;
    expectedAttrValueEntry[2] = PLDM_BIOS_ENUMERATION;

    checkConstructEntry(enumReadWrite, biosStringTable, expectedAttrEntry,
                        expectedAttrValueEntry);

    EXPECT_CALL(dbusHandler,
                getDbusPropertyVariant(StrEq("/xyz/abc/def"), StrEq("Policy"),
                                       StrEq("xyz.openbmc.abc.def")))
        .WillOnce(Return(PropertyValue(true)));

    expectedAttrValueEntry = {
        0, 0, /* attr handle */
        0,    /* attr type enum read-write*/
        1,    /* number of current value */
        0     /* current value string handle index */
    };

    checkConstructEntry(enumReadWrite, biosStringTable, expectedAttrEntry,
                        expectedAttrValueEntry);
}

TEST_F(TestBIOSEnumAttribute, setAttrValueOnDbus)
{
    MockBIOSStringTable biosStringTable;
    MockdBusHandler dbusHandler;

    auto jsonEnumReadWrite = R"({
         "attribute_name" : "CodeUpdatePolicy",
         "possible_values" : [ "Concurrent", "Disruptive" ],
         "default_values" : [ "Disruptive" ],
         "readOnly" : false,
         "helpText" : "HelpText",
         "displayName" : "DisplayName",
         "dbus":
            {
               "object_path" : "/xyz/abc/def",
               "interface" : "xyz.openbmc.abc.def",
               "property_name" : "Policy",
               "property_type" : "bool",
               "property_values" : [true, false]
          }
      })"_json;
    DBusMapping dbusMapping{"/xyz/abc/def", "xyz.openbmc.abc.def", "Policy",
                            "bool"};

    BIOSEnumAttribute enumReadWrite{jsonEnumReadWrite, &dbusHandler};

    std::vector<uint8_t> attrEntry{
        0, 0, /* attr handle */
        0,    /* attr type enum read-only*/
        4, 0, /* attr name handle */
        2,    /* number of possible value */
        2, 0, /* possible value handle */
        3, 0, /* possible value handle */
        1,    /* number of default value */
        1     /* defaut value string handle index */
    };

    ON_CALL(biosStringTable, findString(2))
        .WillByDefault(Return(std::string("Concurrent")));
    ON_CALL(biosStringTable, findString(3))
        .WillByDefault(Return(std::string("Disruptive")));

    std::vector<uint8_t> attrValueEntry{
        0, 0, /* attr handle */
        0,    /* attr type enum read-only*/
        1,    /* number of current value */
        0     /* current value string handle index */
    };

    EXPECT_CALL(dbusHandler,
                setDbusProperty(dbusMapping, PropertyValue{bool(true)}))
        .Times(1);
    enumReadWrite.setAttrValueOnDbus(
        reinterpret_cast<pldm_bios_attr_val_table_entry*>(
            attrValueEntry.data()),
        reinterpret_cast<pldm_bios_attr_table_entry*>(attrEntry.data()),
        biosStringTable);
}
