#include "extensions/openpower-pels/data_interface.hpp"
#include "extensions/openpower-pels/host_interface.hpp"
#include "extensions/openpower-pels/journal.hpp"

#include <fcntl.h>

#include <sdeventplus/source/io.hpp>

#include <filesystem>

#include <gmock/gmock.h>

namespace openpower
{
namespace pels
{

class MockDataInterface : public DataInterfaceBase
{
  public:
    MockDataInterface()
    {
        ON_CALL(*this, checkDumpStatus)
            .WillByDefault(
                ::testing::Return(std::vector<bool>({false, false, false})));
    }

    MOCK_METHOD(std::string, getMachineTypeModel, (), (const override));
    MOCK_METHOD(std::string, getMachineSerialNumber, (), (const override));
    MOCK_METHOD(std::string, getServerFWVersion, (), (const override));
    MOCK_METHOD(std::string, getBMCFWVersion, (), (const override));
    MOCK_METHOD(std::string, getBMCFWVersionID, (), (const override));
    MOCK_METHOD(bool, getHostPELEnablement, (), (const override));
    MOCK_METHOD(std::string, getBMCState, (), (const override));
    MOCK_METHOD(std::string, getChassisState, (), (const override));
    MOCK_METHOD(std::string, getHostState, (), (const override));
    MOCK_METHOD(std::string, getMotherboardCCIN, (), (const override));
    MOCK_METHOD(void, getHWCalloutFields,
                (const std::string&, std::string&, std::string&, std::string&),
                (const override));
    MOCK_METHOD(std::string, getLocationCode, (const std::string&),
                (const override));
    MOCK_METHOD(std::vector<std::string>, getSystemNames, (), (const override));
    MOCK_METHOD(std::string, expandLocationCode, (const std::string&, uint16_t),
                (const override));
    MOCK_METHOD(std::vector<std::string>, getInventoryFromLocCode,
                (const std::string&, uint16_t, bool), (const override));
    MOCK_METHOD(void, assertLEDGroup, (const std::string&, bool),
                (const override));
    MOCK_METHOD(void, setFunctional, (const std::string&, bool),
                (const override));
    MOCK_METHOD(std::vector<uint8_t>, getSystemIMKeyword, (), (const override));
    MOCK_METHOD(bool, getQuiesceOnError, (), (const override));
    MOCK_METHOD(void, setCriticalAssociation, (const std::string&),
                (const override));
    MOCK_METHOD(std::vector<bool>, checkDumpStatus,
                (const std::vector<std::string>&), (const override));
    MOCK_METHOD(std::string, getBootState, (), (const override));
    MOCK_METHOD(void, createGuardRecord,
                (const std::vector<uint8_t>&, const std::string&,
                 const std::string&),
                (const override));
    MOCK_METHOD(void, createProgressSRC,
                (const uint64_t&, const std::vector<uint8_t>&),
                (const override));
    MOCK_METHOD(std::vector<uint32_t>, getLogIDWithHwIsolation, (),
                (const override));
    MOCK_METHOD(std::vector<uint8_t>, getRawProgressSRC, (), (const override));
    MOCK_METHOD(std::optional<std::vector<uint8_t>>, getDIProperty,
                (const std::string&), (const override));

    void changeHostState(bool newState)
    {
        setHostUp(newState);
    }

    void setHMCManaged(bool managed)
    {
        _hmcManaged = managed;
    }

    void fruPresent(const std::string& locationCode)
    {
        setFruPresent(locationCode);
    }
};

/**
 * @brief The mock HostInterface class
 *
 * This replaces the PLDM calls with a FIFO for the asynchronous
 * responses.
 */
class MockHostInterface : public HostInterface
{
  public:
    /**
     * @brief Constructor
     *
     * @param[in] event - The sd_event object
     * @param[in] dataIface - The DataInterface class
     */
    MockHostInterface(sd_event* event, DataInterfaceBase& dataIface) :
        HostInterface(event, dataIface)
    {
        char templ[] = "/tmp/cmdfifoXXXXXX";
        std::filesystem::path dir = mkdtemp(templ);
        _fifo = dir / "fifo";
    }

    /**
     * @brief Destructor
     */
    virtual ~MockHostInterface()
    {
        std::filesystem::remove_all(_fifo.parent_path());
    }

    MOCK_METHOD(CmdStatus, sendNewLogCmd, (uint32_t, uint32_t), (override));

    /**
     * @brief Cancels waiting for a command response
     */
    virtual void cancelCmd() override
    {
        _inProgress = false;
        _source = nullptr;
    }

    /**
     * @brief Returns the amount of time to wait before retrying after
     *        a failed send command.
     *
     * @return milliseconds - The amount of time to wait
     */
    virtual std::chrono::milliseconds getSendRetryDelay() const override
    {
        return std::chrono::milliseconds(2);
    }

    /**
     * @brief Returns the amount of time to wait before retrying after
     *        a command receive.
     *
     * @return milliseconds - The amount of time to wait
     */
    virtual std::chrono::milliseconds getReceiveRetryDelay() const override
    {
        return std::chrono::milliseconds(2);
    }

    /**
     * @brief Returns the amount of time to wait before retrying if the
     *        host firmware's PEL storage was full and it can't store
     *        any more logs until it is freed up somehow.
     *
     * @return milliseconds - The amount of time to wait
     */
    virtual std::chrono::milliseconds getHostFullRetryDelay() const override
    {
        return std::chrono::milliseconds(400);
    }

    /**
     * @brief Returns the amount of time to wait after the host is up
     *        before sending commands.
     *
     * @return milliseconds - The amount of time to wait
     */
    virtual std::chrono::milliseconds getHostUpDelay() const override
    {
        return std::chrono::milliseconds(0);
    }

    /**
     * @brief Returns the number of commands processed
     */
    size_t numCmdsProcessed() const
    {
        return _cmdsProcessed;
    }

    /**
     * @brief Writes the data passed in to the FIFO
     *
     * @param[in] hostResponse - use a 0 to indicate success
     *
     * @return CmdStatus - success or failure
     */
    CmdStatus send(uint8_t hostResponse)
    {
        // Create a FIFO once.
        if (!std::filesystem::exists(_fifo))
        {
            if (mkfifo(_fifo.c_str(), 0622))
            {
                ADD_FAILURE() << "Failed mkfifo " << _fifo << strerror(errno);
                exit(-1);
            }
        }

        // Open it and register the reponse callback to
        // be used on FD activity.
        int fd = open(_fifo.c_str(), O_NONBLOCK | O_RDWR);
        EXPECT_TRUE(fd >= 0) << "Unable to open FIFO";

        auto callback =
            [this](sdeventplus::source::IO& source, int fd, uint32_t events) {
                this->receive(source, fd, events, nullptr);
            };

        try
        {
            _source = std::make_unique<sdeventplus::source::IO>(
                _event, fd, EPOLLIN,
                std::bind(callback, std::placeholders::_1,
                          std::placeholders::_2, std::placeholders::_3));
        }
        catch (const std::exception& e)
        {
            ADD_FAILURE() << "Event exception: " << e.what();
            close(fd);
            return CmdStatus::failure;
        }

        // Write the fake host reponse to the FIFO
        auto bytesWritten = write(fd, &hostResponse, sizeof(hostResponse));
        EXPECT_EQ(bytesWritten, sizeof(hostResponse));

        _inProgress = true;

        return CmdStatus::success;
    }

  protected:
    /**
     * @brief Reads the data written to the fifo and then calls
     *        the subscriber's callback.
     *
     * Nonzero data indicates a command failure (for testing bad path).
     *
     * @param[in] source - The event source object
     * @param[in] fd - The file descriptor used
     * @param[in] events - The event bits
     */
    void receive(sdeventplus::source::IO& /*source*/, int /*fd*/,
                 uint32_t events, pldm_transport* /*transport*/) override
    {
        if (!(events & EPOLLIN))
        {
            return;
        }

        _inProgress = false;

        int newFD = open(_fifo.c_str(), O_NONBLOCK | O_RDONLY);
        ASSERT_TRUE(newFD >= 0) << "Failed to open FIFO";

        // Read the host success/failure response from the FIFO.
        uint8_t data;
        auto bytesRead = read(newFD, &data, sizeof(data));
        EXPECT_EQ(bytesRead, sizeof(data));

        close(newFD);

        ResponseStatus status = ResponseStatus::success;
        if (data != 0)
        {
            status = ResponseStatus::failure;
        }

        callResponseFunc(status);

        // Keep account of the number of commands responses for testing.
        _cmdsProcessed++;
    }

  private:
    /**
     * @brief The event source for the fifo
     */
    std::unique_ptr<sdeventplus::source::IO> _source;

    /**
     * @brief the path to the fifo
     */
    std::filesystem::path _fifo;

    /**
     * @brief The number of commands processed
     */
    size_t _cmdsProcessed = 0;
};

class MockJournal : public JournalBase
{
  public:
    MockJournal() {}

    MOCK_METHOD(std::vector<std::string>, getMessages,
                (const std::string&, size_t), (const override));

    MOCK_METHOD(void, sync, (), (const override));
};

} // namespace pels
} // namespace openpower
