/**
 * Copyright © 2019 IBM Corporation
 *
 * 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 "extensions/openpower-pels/data_interface.hpp"
#include "extensions/openpower-pels/host_notifier.hpp"
#include "mocks.hpp"
#include "pel_utils.hpp"

#include <fcntl.h>
#include <sys/stat.h>
#include <sys/types.h>

#include <chrono>

#include <gtest/gtest.h>

using namespace openpower::pels;
using ::testing::_;
using ::testing::Invoke;
using ::testing::NiceMock;
using ::testing::Return;
namespace fs = std::filesystem;
using namespace std::chrono;

const size_t actionFlags0Offset = 66;
const size_t actionFlags1Offset = 67;

class HostNotifierTest : public CleanPELFiles
{
  public:
    HostNotifierTest() : repo(repoPath)
    {
        auto r = sd_event_default(&event);
        EXPECT_TRUE(r >= 0);

        ON_CALL(dataIface, getHostPELEnablement).WillByDefault(Return(true));

        hostIface = std::make_unique<NiceMock<MockHostInterface>>(event,
                                                                  dataIface);

        mockHostIface = reinterpret_cast<MockHostInterface*>(hostIface.get());

        auto send = [this](uint32_t /*id*/, uint32_t /*size*/) {
            return this->mockHostIface->send(0);
        };

        // Unless otherwise specified, sendNewLogCmd should always pass.
        ON_CALL(*mockHostIface, sendNewLogCmd(_, _))
            .WillByDefault(Invoke(send));
    }

    ~HostNotifierTest()
    {
        sd_event_unref(event);
    }

  protected:
    sd_event* event;
    Repository repo;
    NiceMock<MockDataInterface> dataIface;
    std::unique_ptr<HostInterface> hostIface;
    MockHostInterface* mockHostIface;
};

/**
 * @brief Create PEL with the specified action flags
 *
 * @param[in] actionFlagsMask - Optional action flags to use
 *
 * @return std::unique_ptr<PEL>
 */
std::unique_ptr<PEL> makePEL(uint16_t actionFlagsMask = 0)
{
    static uint32_t obmcID = 1;
    auto data = pelDataFactory(TestPELType::pelSimple);

    data[actionFlags0Offset] |= actionFlagsMask >> 8;
    data[actionFlags1Offset] |= actionFlagsMask & 0xFF;

    auto pel = std::make_unique<PEL>(data, obmcID++);
    pel->assignID();
    pel->setCommitTime();
    return pel;
}

/**
 * @brief Run an iteration of the event loop.
 *
 * An event loop is used for:
 *   1) timer expiration callbacks
 *   2) Dispatches
 *   3) host interface receive callbacks
 *
 * @param[in] event - The event object
 * @param[in] numEvents - number of times to call Event::run()
 * @param[in] timeout - timeout value for run()
 */
void runEvents(sdeventplus::Event& event, size_t numEvents,
               milliseconds timeout = milliseconds(1))
{
    for (size_t i = 0; i < numEvents; i++)
    {
        event.run(timeout);
    }
}

// Test that host state change callbacks work
TEST_F(HostNotifierTest, TestHostStateChange)
{
    bool hostState = false;
    bool called = false;
    DataInterfaceBase::HostStateChangeFunc func =
        [&hostState, &called](bool state) {
        hostState = state;
        called = true;
    };

    dataIface.subscribeToHostStateChange("test", func);

    // callback called
    dataIface.changeHostState(true);
    EXPECT_TRUE(called);
    EXPECT_TRUE(hostState);

    // No change, not called
    called = false;
    dataIface.changeHostState(true);
    EXPECT_FALSE(called);

    // Called again
    dataIface.changeHostState(false);
    EXPECT_FALSE(hostState);
    EXPECT_TRUE(called);

    // Shouldn't get called after an unsubscribe
    dataIface.unsubscribeFromHostStateChange("test");

    called = false;

    dataIface.changeHostState(true);
    EXPECT_FALSE(called);
}

// Test dealing with how acked PELs are put on the
// notification queue.
TEST_F(HostNotifierTest, TestPolicyAckedPEL)
{
    HostNotifier notifier{repo, dataIface, std::move(hostIface)};

    auto pel = makePEL();
    repo.add(pel);

    // This is required
    EXPECT_TRUE(notifier.enqueueRequired(pel->id()));
    EXPECT_TRUE(notifier.notifyRequired(pel->id()));

    // Not in the repo
    EXPECT_FALSE(notifier.enqueueRequired(42));
    EXPECT_FALSE(notifier.notifyRequired(42));

    // Now set this PEL to host acked
    repo.setPELHostTransState(pel->id(), TransmissionState::acked);

    // Since it's acked, doesn't need to be enqueued or transmitted
    EXPECT_FALSE(notifier.enqueueRequired(pel->id()));
    EXPECT_FALSE(notifier.notifyRequired(pel->id()));
}

// Test the 'don't report' PEL flag
TEST_F(HostNotifierTest, TestPolicyDontReport)
{
    HostNotifier notifier{repo, dataIface, std::move(hostIface)};

    // dontReportToHostFlagBit
    auto pel = makePEL(0x1000);

    // Double check the action flag is still set
    std::bitset<16> actionFlags = pel->userHeader().actionFlags();
    EXPECT_TRUE(actionFlags.test(dontReportToHostFlagBit));

    repo.add(pel);

    // Don't need to send this to the host
    EXPECT_FALSE(notifier.enqueueRequired(pel->id()));
}

// Test that hidden PELs need notification when there
// is no HMC.
TEST_F(HostNotifierTest, TestPolicyHiddenNoHMC)
{
    HostNotifier notifier{repo, dataIface, std::move(hostIface)};

    // hiddenFlagBit
    auto pel = makePEL(0x4000);

    // Double check the action flag is still set
    std::bitset<16> actionFlags = pel->userHeader().actionFlags();
    EXPECT_TRUE(actionFlags.test(hiddenFlagBit));

    repo.add(pel);

    // Still need to enqueue this
    EXPECT_TRUE(notifier.enqueueRequired(pel->id()));

    // Still need to send it
    EXPECT_TRUE(notifier.notifyRequired(pel->id()));
}

// Don't need to enqueue a hidden log already acked by the HMC
TEST_F(HostNotifierTest, TestPolicyHiddenWithHMCAcked)
{
    HostNotifier notifier{repo, dataIface, std::move(hostIface)};

    // hiddenFlagBit
    auto pel = makePEL(0x4000);

    // Double check the action flag is still set
    std::bitset<16> actionFlags = pel->userHeader().actionFlags();
    EXPECT_TRUE(actionFlags.test(hiddenFlagBit));

    repo.add(pel);

    // No HMC yet, so required
    EXPECT_TRUE(notifier.enqueueRequired(pel->id()));

    repo.setPELHMCTransState(pel->id(), TransmissionState::acked);

    // Not required anymore
    EXPECT_FALSE(notifier.enqueueRequired(pel->id()));
}

// Test that changing the HMC manage status affects
// the policy with hidden log notification.
TEST_F(HostNotifierTest, TestPolicyHiddenWithHMCManaged)
{
    HostNotifier notifier{repo, dataIface, std::move(hostIface)};

    // hiddenFlagBit
    auto pel = makePEL(0x4000);

    repo.add(pel);

    // The first time, the HMC managed is false
    EXPECT_TRUE(notifier.notifyRequired(pel->id()));

    dataIface.setHMCManaged(true);

    // This time, HMC managed is true so no need to notify
    EXPECT_FALSE(notifier.notifyRequired(pel->id()));
}

// Test that PELs are enqueued on startup
TEST_F(HostNotifierTest, TestStartup)
{
    // Give the repo 10 PELs to start with
    for (int i = 0; i < 10; i++)
    {
        auto pel = makePEL();
        repo.add(pel);
    }

    HostNotifier notifier{repo, dataIface, std::move(hostIface)};

    ASSERT_EQ(notifier.queueSize(), 10);

    // Now add 10 more after the notifier is watching
    for (int i = 0; i < 10; i++)
    {
        auto pel = makePEL();
        repo.add(pel);
    }

    ASSERT_EQ(notifier.queueSize(), 20);
}

// Test the simple path were PELs get sent to the host
TEST_F(HostNotifierTest, TestSendCmd)
{
    sdeventplus::Event sdEvent{event};

    HostNotifier notifier{repo, dataIface, std::move(hostIface)};

    // Add a PEL with the host off
    auto pel = makePEL();
    repo.add(pel);

    EXPECT_EQ(notifier.queueSize(), 1);

    dataIface.changeHostState(true);

    runEvents(sdEvent, 2);

    // It was sent up
    EXPECT_EQ(mockHostIface->numCmdsProcessed(), 1);
    EXPECT_EQ(notifier.queueSize(), 0);

    // Verify the state was written to the PEL.
    Repository::LogID id{Repository::LogID::Pel{pel->id()}};
    auto data = repo.getPELData(id);
    PEL pelFromRepo{*data};
    EXPECT_EQ(pelFromRepo.hostTransmissionState(), TransmissionState::sent);

    // Add a few more PELs.  They will get sent.
    pel = makePEL();
    repo.add(pel);

    // Dispatch it by hitting the event loop (no commands sent yet)
    // Don't need to test this step discretely in the future
    runEvents(sdEvent, 1);
    EXPECT_EQ(mockHostIface->numCmdsProcessed(), 1);
    EXPECT_EQ(notifier.queueSize(), 0);

    // Send the command
    runEvents(sdEvent, 1);

    EXPECT_EQ(mockHostIface->numCmdsProcessed(), 2);
    EXPECT_EQ(notifier.queueSize(), 0);

    pel = makePEL();
    repo.add(pel);

    // dispatch and process the command
    runEvents(sdEvent, 2);

    EXPECT_EQ(mockHostIface->numCmdsProcessed(), 3);
    EXPECT_EQ(notifier.queueSize(), 0);
}

// Test that if the class is created with the host up,
// it will send PELs
TEST_F(HostNotifierTest, TestStartAfterHostUp)
{
    // Add PELs right away
    auto pel = makePEL();
    repo.add(pel);
    pel = makePEL();
    repo.add(pel);

    sdeventplus::Event sdEvent{event};

    // Create the HostNotifier class with the host already up
    dataIface.changeHostState(true);
    HostNotifier notifier{repo, dataIface, std::move(hostIface)};

    // It should start sending PELs right away
    runEvents(sdEvent, 3);

    EXPECT_EQ(mockHostIface->numCmdsProcessed(), 2);
    EXPECT_EQ(notifier.queueSize(), 0);
}

// Test that a single failure will cause a retry
TEST_F(HostNotifierTest, TestHostRetry)
{
    sdeventplus::Event sdEvent{event};

    HostNotifier notifier{repo, dataIface, std::move(hostIface)};

    auto sendFailure = [this](uint32_t /*id*/, uint32_t /*size*/) {
        return this->mockHostIface->send(1);
    };
    auto sendSuccess = [this](uint32_t /*id*/, uint32_t /*size*/) {
        return this->mockHostIface->send(0);
    };

    EXPECT_CALL(*mockHostIface, sendNewLogCmd(_, _))
        .WillOnce(Invoke(sendFailure))
        .WillOnce(Invoke(sendSuccess))
        .WillOnce(Invoke(sendSuccess));

    dataIface.changeHostState(true);

    auto pel = makePEL();
    repo.add(pel);

    // Dispatch and handle the command
    runEvents(sdEvent, 2);

    // The command failed, so the queue isn't empty
    EXPECT_EQ(mockHostIface->numCmdsProcessed(), 1);
    EXPECT_EQ(notifier.queueSize(), 1);

    // Run the events again to let the timer expire and the
    // command to be retried, which will be successful.
    runEvents(sdEvent, 2, mockHostIface->getReceiveRetryDelay());

    EXPECT_EQ(mockHostIface->numCmdsProcessed(), 2);
    EXPECT_EQ(notifier.queueSize(), 0);

    // This one should pass with no problems
    pel = makePEL();
    repo.add(pel);

    // Dispatch and handle the command
    runEvents(sdEvent, 2);

    EXPECT_EQ(mockHostIface->numCmdsProcessed(), 3);
    EXPECT_EQ(notifier.queueSize(), 0);
}

// Test that all commands fail and notifier will give up
TEST_F(HostNotifierTest, TestHardFailure)
{
    sdeventplus::Event sdEvent{event};

    HostNotifier notifier{repo, dataIface, std::move(hostIface)};

    // Every call will fail
    auto sendFailure = [this](uint32_t /*id*/, uint32_t /*size*/) {
        return this->mockHostIface->send(1);
    };

    EXPECT_CALL(*mockHostIface, sendNewLogCmd(_, _))
        .WillRepeatedly(Invoke(sendFailure));

    dataIface.changeHostState(true);

    auto pel = makePEL();
    repo.add(pel);

    // Clock more retries than necessary
    runEvents(sdEvent, 40, mockHostIface->getReceiveRetryDelay());

    // Should have stopped after the 15 Tries
    EXPECT_EQ(mockHostIface->numCmdsProcessed(), 15);
    EXPECT_EQ(notifier.queueSize(), 1);

    // Now add another PEL, and it should start trying again
    // though it will also eventually give up
    pel = makePEL();
    repo.add(pel);

    runEvents(sdEvent, 40, mockHostIface->getReceiveRetryDelay());

    // Tried an additional 15 times
    EXPECT_EQ(mockHostIface->numCmdsProcessed(), 30);
    EXPECT_EQ(notifier.queueSize(), 2);
}

// Cancel an in progress command
TEST_F(HostNotifierTest, TestCancelCmd)
{
    sdeventplus::Event sdEvent{event};
    HostNotifier notifier{repo, dataIface, std::move(hostIface)};

    dataIface.changeHostState(true);

    // Add and send one PEL, but don't enter the event loop
    // so the receive function can't run.
    auto pel = makePEL();
    repo.add(pel);

    // Not dispatched yet
    EXPECT_EQ(notifier.queueSize(), 1);

    // Dispatch it
    runEvents(sdEvent, 2);

    // It was sent and off the queue
    EXPECT_EQ(notifier.queueSize(), 0);

    // This will cancel the receive
    dataIface.changeHostState(false);

    // Back on the queue
    EXPECT_EQ(notifier.queueSize(), 1);

    // Turn the host back on and make sure
    // commands will work again
    dataIface.changeHostState(true);

    runEvents(sdEvent, 1);

    EXPECT_EQ(mockHostIface->numCmdsProcessed(), 1);
    EXPECT_EQ(notifier.queueSize(), 0);
}

// Test that acking a PEL persist across power cycles
TEST_F(HostNotifierTest, TestPowerCycleAndAcks)
{
    sdeventplus::Event sdEvent{event};

    HostNotifier notifier{repo, dataIface, std::move(hostIface)};

    // Add 2 PELs with host off
    auto pel = makePEL();
    repo.add(pel);
    auto id1 = pel->id();

    pel = makePEL();
    repo.add(pel);
    auto id2 = pel->id();

    dataIface.changeHostState(true);

    runEvents(sdEvent, 3);

    // The were both sent.
    EXPECT_EQ(mockHostIface->numCmdsProcessed(), 2);
    EXPECT_EQ(notifier.queueSize(), 0);

    dataIface.changeHostState(false);

    // Those PELs weren't acked, so they will get sent again
    EXPECT_EQ(notifier.queueSize(), 2);

    // Power back on and send them again
    dataIface.changeHostState(true);
    runEvents(sdEvent, 3);

    EXPECT_EQ(mockHostIface->numCmdsProcessed(), 4);
    EXPECT_EQ(notifier.queueSize(), 0);

    // Ack them and verify the state in the PEL.
    notifier.ackPEL(id1);
    notifier.ackPEL(id2);

    Repository::LogID id{Repository::LogID::Pel{id1}};
    auto data = repo.getPELData(id);
    PEL pelFromRepo1{*data};
    EXPECT_EQ(pelFromRepo1.hostTransmissionState(), TransmissionState::acked);

    id.pelID.id = id2;
    data = repo.getPELData(id);
    PEL pelFromRepo2{*data};
    EXPECT_EQ(pelFromRepo2.hostTransmissionState(), TransmissionState::acked);

    // Power back off, and they should't get re-added
    dataIface.changeHostState(false);

    EXPECT_EQ(notifier.queueSize(), 0);
}

// Test the host full condition
TEST_F(HostNotifierTest, TestHostFull)
{
    // The full interaction with the host is:
    // BMC:  new PEL available
    // Host: ReadPELFile  (not modeled here)
    // Host: Ack(id) (if not full), or HostFull(id)
    // BMC: if full and any new PELs come in, don't sent them
    // Start a timer and try again
    // Host responds with either Ack or full
    // and repeat

    sdeventplus::Event sdEvent{event};
    HostNotifier notifier{repo, dataIface, std::move(hostIface)};

    dataIface.changeHostState(true);

    // Add and dispatch/send one PEL
    auto pel = makePEL();
    auto id = pel->id();
    repo.add(pel);
    runEvents(sdEvent, 2);

    EXPECT_EQ(mockHostIface->numCmdsProcessed(), 1);
    EXPECT_EQ(notifier.queueSize(), 0);

    // Host is full
    notifier.setHostFull(id);

    // It goes back on the queue
    EXPECT_EQ(notifier.queueSize(), 1);

    // The transmission state goes back to new
    Repository::LogID i{Repository::LogID::Pel{id}};
    auto data = repo.getPELData(i);
    PEL pelFromRepo{*data};
    EXPECT_EQ(pelFromRepo.hostTransmissionState(), TransmissionState::newPEL);

    // Clock it, nothing should be sent still.
    runEvents(sdEvent, 1);

    EXPECT_EQ(mockHostIface->numCmdsProcessed(), 1);
    EXPECT_EQ(notifier.queueSize(), 1);

    // Add another PEL and clock it, still nothing sent
    pel = makePEL();
    repo.add(pel);
    runEvents(sdEvent, 2);
    EXPECT_EQ(mockHostIface->numCmdsProcessed(), 1);
    EXPECT_EQ(notifier.queueSize(), 2);

    // Let the host full timer expire to trigger a retry.
    // Add some extra event passes just to be sure nothing new is sent.
    runEvents(sdEvent, 5, mockHostIface->getHostFullRetryDelay());

    // The timer expiration will send just the 1, not both
    EXPECT_EQ(mockHostIface->numCmdsProcessed(), 2);
    EXPECT_EQ(notifier.queueSize(), 1);

    // Host still full
    notifier.setHostFull(id);

    // Let the host full timer attempt again
    runEvents(sdEvent, 2, mockHostIface->getHostFullRetryDelay());
    EXPECT_EQ(mockHostIface->numCmdsProcessed(), 3);

    // Add yet another PEL with the retry timer expired.
    // It shouldn't get sent out.
    pel = makePEL();
    repo.add(pel);
    runEvents(sdEvent, 2);
    EXPECT_EQ(mockHostIface->numCmdsProcessed(), 3);

    // The last 2 PELs still on the queue
    EXPECT_EQ(notifier.queueSize(), 2);

    // Host no longer full, it finally acks the first PEL
    notifier.ackPEL(id);

    // Now the remaining 2 PELs will be dispatched
    runEvents(sdEvent, 3);

    EXPECT_EQ(mockHostIface->numCmdsProcessed(), 5);
    EXPECT_EQ(notifier.queueSize(), 0);
}

// Test when the host says it was send a malformed PEL
TEST_F(HostNotifierTest, TestBadPEL)
{
    sdeventplus::Event sdEvent{event};

    {
        Repository repo1{repoPath};
        HostNotifier notifier{repo1, dataIface, std::move(hostIface)};

        dataIface.changeHostState(true);

        // Add a PEL and dispatch and send it
        auto pel = makePEL();
        auto id = pel->id();
        repo1.add(pel);

        runEvents(sdEvent, 2);
        EXPECT_EQ(mockHostIface->numCmdsProcessed(), 1);
        EXPECT_EQ(notifier.queueSize(), 0);

        // The host rejected it.
        notifier.setBadPEL(id);

        // Doesn't go back on the queue
        EXPECT_EQ(notifier.queueSize(), 0);

        // Check the state was saved in the PEL itself
        Repository::LogID i{Repository::LogID::Pel{id}};
        auto data = repo1.getPELData(i);
        PEL pelFromRepo{*data};
        EXPECT_EQ(pelFromRepo.hostTransmissionState(),
                  TransmissionState::badPEL);

        dataIface.changeHostState(false);

        // Ensure it doesn't go back on the queue on a power cycle
        EXPECT_EQ(notifier.queueSize(), 0);
    }

    // Now restore the repo, and make sure it doesn't come back
    {
        Repository repo1{repoPath};

        std::unique_ptr<HostInterface> hostIface1 =
            std::make_unique<MockHostInterface>(event, dataIface);

        HostNotifier notifier{repo1, dataIface, std::move(hostIface1)};

        EXPECT_EQ(notifier.queueSize(), 0);
    }
}

// Test that sending PELs can be disabled
TEST_F(HostNotifierTest, TestDisable)
{
    // Turn off sending the PELs except for once in the middle
    EXPECT_CALL(dataIface, getHostPELEnablement())
        .WillOnce(Return(false))
        .WillOnce(Return(false))
        .WillOnce(Return(true))
        .WillOnce(Return(false))
        .WillOnce(Return(false))
        .WillOnce(Return(false));

    {
        HostNotifier notifier{repo, dataIface, std::move(hostIface)};

        // Add a PEL with the host off
        auto pel = makePEL();
        repo.add(pel);

        // Not added to the send queue
        EXPECT_EQ(notifier.queueSize(), 0);

        dataIface.changeHostState(true);

        // Try again with the host on
        pel = makePEL();
        repo.add(pel);

        EXPECT_EQ(notifier.queueSize(), 0);

        // Now getHostPELEnablement() will return true for the new PEL
        pel = makePEL();
        repo.add(pel);

        EXPECT_EQ(notifier.queueSize(), 1);
    }

    // getHostPELEnablement is back to returning false.
    // Create a new second instance and make sure the 3 existing PELs
    // aren't put on the queue on startup
    {
        Repository repo1{repoPath};
        std::unique_ptr<HostInterface> hostIface1 =
            std::make_unique<MockHostInterface>(event, dataIface);

        HostNotifier notifier{repo1, dataIface, std::move(hostIface1)};

        EXPECT_EQ(notifier.queueSize(), 0);
    }
}
