// SPDX-License-Identifier: Apache-2.0
// Copyright (C) 2021 Google

#include "buffer_service.hpp"
#include "config.hpp"
#include "dbus_loop_mock.hpp"
#include "file_storage_mock.hpp"
#include "host_console_mock.hpp"
#include "log_buffer_mock.hpp"

#include <memory>
#include <string>
#include <system_error>

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

namespace
{

constexpr char firstDatagram[] = "Hello world";
// Shouldn't read more than maximum size of a datagram.
constexpr int consoleReadMaxSize = 1024;

using ::testing::_;
using ::testing::DoAll;
using ::testing::Eq;
using ::testing::InSequence;
using ::testing::Le;
using ::testing::Ref;
using ::testing::Return;
using ::testing::SetArrayArgument;
using ::testing::StrEq;
using ::testing::Test;
using ::testing::Throw;

// A helper class that owns config.
struct ConfigInTest
{
    Config config;
    ConfigInTest() : config() {}
};

class BufferServiceTest : public Test, public ConfigInTest, public BufferService
{
  public:
    // ConfigInTest::config is initialized before BufferService.
    BufferServiceTest() :
        BufferService(ConfigInTest::config, dbusLoopMock, hostConsoleMock,
                      logBufferMock, fileStorageMock)
    {}

    MOCK_METHOD(void, flush, (), (override));
    MOCK_METHOD(void, readConsole, (), (override));

  protected:
    // Set hostConsole firstly read specified data and then read nothing.
    void setHostConsoleOnce(const char* data, size_t len)
    {
        EXPECT_CALL(hostConsoleMock, read(_, Le(consoleReadMaxSize)))
            .WillOnce(DoAll(SetArrayArgument<0>(data, data + len), Return(len)))
            .WillOnce(Return(0));
    }

    DbusLoopMock dbusLoopMock;
    HostConsoleMock hostConsoleMock;
    LogBufferMock logBufferMock;
    FileStorageMock fileStorageMock;
};

TEST_F(BufferServiceTest, FlushEmptyBuffer)
{
    EXPECT_CALL(logBufferMock, empty()).WillOnce(Return(true));
    EXPECT_NO_THROW(BufferService::flush());
}

TEST_F(BufferServiceTest, FlushExceptionCaught)
{
    InSequence sequence;
    EXPECT_CALL(logBufferMock, empty()).WillOnce(Return(false));
    EXPECT_CALL(fileStorageMock, save(Ref(logBufferMock)))
        .WillOnce(Throw(std::runtime_error("Mock error")));
    EXPECT_NO_THROW(BufferService::flush());
}

TEST_F(BufferServiceTest, FlushOk)
{
    InSequence sequence;
    EXPECT_CALL(logBufferMock, empty()).WillOnce(Return(false));
    EXPECT_CALL(fileStorageMock, save(Ref(logBufferMock)));
    EXPECT_CALL(logBufferMock, clear());
    EXPECT_NO_THROW(BufferService::flush());
}

TEST_F(BufferServiceTest, ReadConsoleExceptionCaught)
{
    InSequence sequence;
    // Shouldn't read more than maximum size of a datagram.
    EXPECT_CALL(hostConsoleMock, read(_, Le(1024)))
        .WillOnce(Throw(std::system_error(std::error_code(), "Mock error")));
    EXPECT_NO_THROW(BufferService::readConsole());
}

TEST_F(BufferServiceTest, ReadConsoleOk)
{
    setHostConsoleOnce(firstDatagram, strlen(firstDatagram));
    EXPECT_CALL(logBufferMock,
                append(StrEq(firstDatagram), Eq(strlen(firstDatagram))))
        .WillOnce(Return());
    EXPECT_NO_THROW(BufferService::readConsole());
}

TEST_F(BufferServiceTest, RunIoRegisterError)
{
    EXPECT_CALL(hostConsoleMock, connect()).WillOnce(Return());
    EXPECT_CALL(dbusLoopMock, addSignalHandler(Eq(SIGUSR1), _))
        .WillOnce(Return());
    EXPECT_CALL(dbusLoopMock, addSignalHandler(Eq(SIGTERM), _))
        .WillOnce(Return());
    EXPECT_CALL(dbusLoopMock, addIoHandler(Eq(int(hostConsoleMock)), _))
        .WillOnce(Throw(std::runtime_error("Mock error")));
    EXPECT_THROW(run(), std::runtime_error);
}

TEST_F(BufferServiceTest, RunSignalRegisterError)
{
    EXPECT_CALL(hostConsoleMock, connect()).WillOnce(Return());
    EXPECT_CALL(dbusLoopMock, addSignalHandler(Eq(SIGUSR1), _))
        .WillOnce(Throw(std::runtime_error("Mock error")));
    EXPECT_THROW(run(), std::runtime_error);
}

TEST_F(BufferServiceTest, RunOk)
{
    ConfigInTest::config.bufFlushFull = true;
    EXPECT_CALL(hostConsoleMock, connect()).WillOnce(Return());
    EXPECT_CALL(dbusLoopMock, addIoHandler(Eq(int(hostConsoleMock)), _))
        .WillOnce(Return());
    EXPECT_CALL(dbusLoopMock, addSignalHandler(Eq(SIGTERM), _))
        .WillOnce(Return());
    EXPECT_CALL(logBufferMock, setFullHandler(_)).WillOnce(Return());
    EXPECT_CALL(dbusLoopMock, addSignalHandler(Eq(SIGUSR1), _))
        .WillOnce(Return());
    EXPECT_CALL(dbusLoopMock,
                addPropertyHandler(StrEq(ConfigInTest::config.hostState), _, _))
        .WillOnce(Return());
    EXPECT_CALL(dbusLoopMock, run).WillOnce(Return(0));
    EXPECT_CALL(logBufferMock, empty()).WillOnce(Return(false));
    EXPECT_CALL(*this, flush()).WillOnce(Return());
    EXPECT_NO_THROW(run());
}
} // namespace
