/*
 * Copyright 2023 Google LLC
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
#include "src/soc-reset-me.hpp"

#include <sdbusplus/test/sdbus_mock.hpp>

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

using ::testing::_;
using ::testing::StrEq;
namespace pldm_oem_google
{
namespace soc_reset_me
{
// PeerSoCId tests
class PeerSoCIdTest : public ::testing::Test
{
    void SetUp() override
    {
        // reset the internal optional
        PeerSoCId::socId.reset();
    }
};
// current implemetation in Athena
// valid instance value is "0", "1"
// instance 0 => CN_1, instance 1 => CN_2
// this unit test to capture this arbitary mapping policy/assumption
// accidently changed in the future
TEST_F(PeerSoCIdTest, SetWithPldmdInstanceParam)
{
    // Test setting with invalid instance (e.g., non-integer).
    EXPECT_FALSE(PeerSoCId::setWithPldmdInstanceParam("invalid"));
    EXPECT_EQ(PeerSoCId::value(), SocId::cnDefault);
    EXPECT_TRUE(PeerSoCId::isDefault());

    // Test setting with an unsupported SoC ID.
    EXPECT_FALSE(PeerSoCId::setWithPldmdInstanceParam("3"));
    EXPECT_EQ(PeerSoCId::value(), SocId::cnDefault);
    EXPECT_TRUE(PeerSoCId::isDefault());

    // Test setting with valid instance: "0"
    EXPECT_TRUE(PeerSoCId::setWithPldmdInstanceParam("0"));
    EXPECT_EQ(PeerSoCId::value(), SocId::cn1);
    EXPECT_FALSE(PeerSoCId::isDefault());
}

TEST_F(PeerSoCIdTest, SetWithPldmdInstanceParam_cn1)
{
    // Test setting with valid instance: "0"
    EXPECT_TRUE(PeerSoCId::setWithPldmdInstanceParam("0"));
    EXPECT_EQ(PeerSoCId::value(), SocId::cn1);
    EXPECT_FALSE(PeerSoCId::isDefault());

    // Test setting with valid instance: "1", immutable after first set
    EXPECT_FALSE(PeerSoCId::setWithPldmdInstanceParam("1"));
    EXPECT_EQ(PeerSoCId::value(), SocId::cn1);
    EXPECT_FALSE(PeerSoCId::isDefault());
}

TEST_F(PeerSoCIdTest, SetWithPldmdInstanceParam_cn2)
{
    // Test setting with valid instance: "1"
    EXPECT_TRUE(PeerSoCId::setWithPldmdInstanceParam("1"));
    EXPECT_EQ(PeerSoCId::value(), SocId::cn2);
    EXPECT_FALSE(PeerSoCId::isDefault());

    // Test setting with valid instance: "0", immutable after first set
    EXPECT_FALSE(PeerSoCId::setWithPldmdInstanceParam("0"));
    EXPECT_EQ(PeerSoCId::value(), SocId::cn2);
    EXPECT_FALSE(PeerSoCId::isDefault());
}

// Test fixture for SocResetMeHandler tests
class SocResetMeHandlerTest : public testing::Test
{
  protected:
    static constexpr auto hostStateReboot =
        "xyz.openbmc_project.State.Host.Transition.Reboot";
    static constexpr auto dbusPropIntf = "org.freedesktop.DBus.Properties";
    ::testing::NiceMock<sdbusplus::SdBusMock> mock;
    static auto dbusParams(SocResetMeHandler& h)
    {
        return h.dbusParams;
    }
    static void resetSoC(SocResetMeHandler& h)
    {
        h.resetSoC(SOC_RESET_ME_AUTO);
    }
    static auto quicentEnd(SocResetMeHandler& h)
    {
        return h.quiescentEnd;
    }
    static void
        mockQuiecentEnd(SocResetMeHandler& h,
                        decltype(SocResetMeHandler::quiescentEnd) mocktime)
    {
        h.quiescentEnd = mocktime;
    }
    void expectNewSetPropMethod(const struct ResetDBusParams* params)
    {
        EXPECT_CALL(mock, sd_bus_message_new_method_call(
                              _, _, StrEq(params->conn), StrEq(params->path),
                              StrEq(dbusPropIntf), StrEq("Set")))
            .WillOnce(::testing::Return(0));
    }
    void expectMessageAppend(const char* val)
    {
        using testing::MatcherCast;
        using testing::Pointee;
        using testing::SafeMatcherCast;
        using ::testing::StrEq;
        EXPECT_CALL(mock, sd_bus_message_append_basic(
                              _, SD_BUS_TYPE_STRING,
                              MatcherCast<const void*>(
                                  SafeMatcherCast<const char*>(StrEq(val)))))
            .WillOnce(::testing::Return(0));
    }
    void expectSetHostTransactionProp(const struct ResetDBusParams* params)
    {
        expectNewSetPropMethod(params);
        expectMessageAppend(params->intf);
        expectMessageAppend(params->prop);
        expectMessageAppend(hostStateReboot);
        // sync call without timeout
        EXPECT_CALL(mock, sd_bus_call(_, _, 0, _, _)).Times(1);
    }

    auto resetMeRequestMsg(uint32_t quiescentPeriod, const char* str)
    {
        std::string_view resetReason{str};

        memset(&data, 0, sizeof(data));
        memcpy(data + sizeof(struct pldm_event_oem_google_soc_reset_me),
               resetReason.data(), resetReason.length());
        auto* msg =
            reinterpret_cast<struct pldm_event_oem_google_soc_reset_me*>(data);
        msg->descLen = resetReason.length();
        msg->resetQuiesent = quiescentPeriod;
        return msg;
    }

    uint8_t data[sizeof(struct pldm_event_oem_google_soc_reset_me) + 128];
};

// Test SocResetMeHandler constructor
TEST_F(SocResetMeHandlerTest, Constructor_InitializeDBusParams)
{
    SocResetMeHandler mockCn1Handler(SocId::cn1,
                                     sdbusplus::get_mocked_new(&mock));
    EXPECT_EQ(dbusParams(mockCn1Handler), cn1DbusParams());
    SocResetMeHandler mockCn2Handler(SocId::cn2,
                                     sdbusplus::get_mocked_new(&mock));
    EXPECT_EQ(dbusParams(mockCn2Handler), cn2DbusParams());
    EXPECT_THROW(SocResetMeHandler mockInvalidHander(
                     SocId::cnDefault, sdbusplus::get_mocked_new(&mock)),
                 InvalidSoCIdException);
    EXPECT_THROW(SocResetMeHandler mockInvalidHander(
                     static_cast<SocId>(-1), sdbusplus::get_mocked_new(&mock)),
                 InvalidSoCIdException);
}

class MockSocResetMeHandler : public SocResetMeHandler
{
  public:
    // Constructor taking the same parameters as SocResetMeHandler
    MockSocResetMeHandler(const SocId id, sdbusplus::bus_t&& b) :
        SocResetMeHandler(id, std::move(b))
    {}

    MOCK_METHOD(void, resetSoC, (const uint16_t resetType), (override));
    MOCK_METHOD(void, logRequest,
                (uint64_t internalInfo, uint16_t resetType,
                 uint32_t quiescentPeriod, const std::string& resetReason),
                (const, override));
    MOCK_METHOD(void, logRequestIgnored, (const ResetTimeStamp& requestTime),
                (const, override));
    MOCK_METHOD(void, logRequestIssued, (const ResetTimeStamp& requestTime),
                (const, override));
};

// First time handling shall not in any reset quiecent period
// so shall reset and update the reset quiecentEnd to
// handleTime + requestQuiesent
TEST_F(SocResetMeHandlerTest, HandleSocResetMeFirstTime)
{
    using std::chrono::seconds;
    using std::chrono::_V2::steady_clock;
    const auto* reason = "HandleSocResetMeFirstTime";
    auto* msg = resetMeRequestMsg(0, reason);

    MockSocResetMeHandler mockHandler(SocId::cn1,
                                      sdbusplus::get_mocked_new(&mock));
    EXPECT_CALL(mockHandler, resetSoC(msg->resetType)).Times(1);
    EXPECT_CALL(mockHandler, logRequest(msg->internalInfo, msg->resetType,
                                        msg->resetQuiesent, StrEq(reason)))
        .Times(1);
    EXPECT_CALL(mockHandler, logRequestIssued(_)).Times(1);
    EXPECT_CALL(mockHandler, logRequestIgnored(_)).Times(0);

    mockHandler.handle(0, msg, msg->descLen + sizeof(*msg));

    EXPECT_EQ(
        duration_cast<seconds>(quicentEnd(mockHandler).time_since_epoch()),
        duration_cast<seconds>(
            (steady_clock::now() + seconds(msg->resetQuiesent))
                .time_since_epoch()));
}

// Following on handling request out of quiencent
// reset SoC and update quiecentEnd to handletTime + requestQuiesent
TEST_F(SocResetMeHandlerTest, HandleSocResetMeOutQuiesent)
{
    using std::chrono::seconds;
    using std::chrono::_V2::steady_clock;
    const auto* reason = "HandleSocResetMeOutQuiesent";
    auto* msg = resetMeRequestMsg(10, reason);
    MockSocResetMeHandler mockHandler(SocId::cn1,
                                      sdbusplus::get_mocked_new(&mock));
    auto mocktime = steady_clock::now() - seconds(30);
    mockQuiecentEnd(mockHandler, mocktime);
    EXPECT_CALL(mockHandler, resetSoC(msg->resetType)).Times(1);
    EXPECT_CALL(mockHandler, logRequest(msg->internalInfo, msg->resetType,
                                        msg->resetQuiesent, StrEq(reason)))
        .Times(1);
    EXPECT_CALL(mockHandler, logRequestIssued(_)).Times(1);
    EXPECT_CALL(mockHandler, logRequestIgnored(_)).Times(0);
    mockHandler.handle(0, msg, msg->descLen + sizeof(*msg));

    EXPECT_EQ(
        duration_cast<seconds>(quicentEnd(mockHandler).time_since_epoch()),
        duration_cast<seconds>(
            (steady_clock::now() + seconds(msg->resetQuiesent))
                .time_since_epoch()));
}

// Following on handling request within quiencent period
// ingore this request and w/o resetting SoC nor updating quiecentEnd
TEST_F(SocResetMeHandlerTest, HandleSocResetMeInQuiesent)
{
    using std::chrono::seconds;
    using std::chrono::_V2::steady_clock;
    const auto* reason = "HandleSocResetMeInQuiesent";
    auto* msg = resetMeRequestMsg(10, reason);

    MockSocResetMeHandler mockHandler(SocId::cn1,
                                      sdbusplus::get_mocked_new(&mock));
    auto mocktime = steady_clock::now() + seconds(30);
    mockQuiecentEnd(mockHandler, mocktime);
    EXPECT_CALL(mockHandler, resetSoC(msg->resetType)).Times(0);
    EXPECT_CALL(mockHandler, logRequest(msg->internalInfo, msg->resetType,
                                        msg->resetQuiesent, StrEq(reason)))
        .Times(1);
    EXPECT_CALL(mockHandler, logRequestIssued(_)).Times(0);
    EXPECT_CALL(mockHandler, logRequestIgnored(_)).Times(1);

    mockHandler.handle(0, msg, sizeof(*msg) + msg->descLen);

    EXPECT_EQ(quicentEnd(mockHandler), mocktime);
}

// Test the expected behavior: set the corresponding state transaction property
TEST_F(SocResetMeHandlerTest, SocResetCn1)
{
    expectSetHostTransactionProp(cn1DbusParams());
    SocResetMeHandler mockHandler(SocId::cn1, sdbusplus::get_mocked_new(&mock));
    resetSoC(mockHandler);
}

TEST_F(SocResetMeHandlerTest, SocResetCn2)
{
    expectSetHostTransactionProp(cn2DbusParams());
    SocResetMeHandler mockHandler(SocId::cn2, sdbusplus::get_mocked_new(&mock));
    resetSoC(mockHandler);
}

} // namespace soc_reset_me
} // namespace pldm_oem_google
