#include <systemd/sd-bus.h>

#include <sdbusplus/exception.hpp>
#include <sdbusplus/test/sdbus_mock.hpp>

#include <cstdlib>
#include <stdexcept>
#include <string>
#include <utility>

#include <gtest/gtest.h>

// Needed for constructor error testing
extern sdbusplus::SdBusImpl sdbus_impl;

namespace
{

using sdbusplus::exception::SdBusError;
using testing::_;
using testing::Return;

TEST(SdBusError, BasicErrno)
{
    const int errorVal = EBUSY;
    const std::string prefix = "BasicErrno";

    // Build the reference sd_bus_error
    sd_bus_error error = SD_BUS_ERROR_NULL;
    EXPECT_EQ(-errorVal, sd_bus_error_set_errno(&error, errorVal));
    EXPECT_TRUE(sd_bus_error_is_set(&error));

    // Build the SdBusError
    SdBusError err(errorVal, prefix.c_str());

    // Make sure inheritance is defined correctly
    sdbusplus::exception::exception& sdbusErr = err;
    SdBusError& errNew = err;
    EXPECT_EQ(errorVal, errNew.get_errno());
    EXPECT_EQ(std::string{error.name}, sdbusErr.name());
    EXPECT_EQ(std::string{error.message}, sdbusErr.description());
    std::exception& stdErr = sdbusErr;
    EXPECT_EQ(prefix + ": " + error.name + ": " + error.message, stdErr.what());

    sd_bus_error_free(&error);
}

TEST(SdBusError, EnomemErrno)
{
    // Make sure no exception is thrown on construction
    SdBusError err(ENOMEM, "EnomemErrno");
}

TEST(SdBusError, NotSetErrno)
{
    const int errorVal = EBUSY;

    sdbusplus::SdBusMock sdbus;
    EXPECT_CALL(sdbus, sd_bus_error_set_errno(_, errorVal))
        .Times(1)
        .WillOnce(Return(errorVal));
    EXPECT_CALL(sdbus, sd_bus_error_is_set(_)).Times(1).WillOnce(Return(false));
    EXPECT_THROW(SdBusError(errorVal, "NotSetErrno", &sdbus),
                 std::runtime_error);
}

TEST(SdBusError, Move)
{
    const int errorVal = EIO;
    const std::string prefix = "Move";

    // Build the reference sd_bus_error
    sd_bus_error error = SD_BUS_ERROR_NULL;
    EXPECT_EQ(-errorVal, sd_bus_error_set_errno(&error, errorVal));
    EXPECT_TRUE(sd_bus_error_is_set(&error));
    const std::string name{error.name};
    const std::string message{error.message};
    const std::string what = prefix + ": " + error.name + ": " + error.message;

    SdBusError errFinal(EBUSY, "Move2");
    // Nest to make sure RAII works for moves
    {
        // Build our first SdBusError
        SdBusError err(errorVal, prefix.c_str());

        EXPECT_EQ(errorVal, err.get_errno());
        EXPECT_EQ(name, err.name());
        EXPECT_EQ(message, err.description());
        EXPECT_EQ(what, err.what());

        // Move our SdBusError to a new one
        SdBusError errNew(std::move(err));

        // Ensure the old object was cleaned up
        EXPECT_EQ(0, err.get_errno());
        EXPECT_EQ(nullptr, err.name());
        EXPECT_EQ(nullptr, err.description());
        EXPECT_EQ(std::string{}, err.what());

        // Ensure our new object has the same data but moved
        EXPECT_EQ(errorVal, errNew.get_errno());
        EXPECT_EQ(name, errNew.name());
        EXPECT_EQ(message, errNew.description());
        EXPECT_EQ(what, errNew.what());

        // Move our SdBusError using the operator=()
        errFinal = std::move(errNew);

        // Ensure the old object was cleaned up
        EXPECT_EQ(0, errNew.get_errno());
        EXPECT_EQ(nullptr, errNew.name());
        EXPECT_EQ(nullptr, errNew.description());
        EXPECT_EQ(std::string{}, errNew.what());
    }

    // Ensure our new object has the same data but moved
    EXPECT_EQ(errorVal, errFinal.get_errno());
    EXPECT_EQ(name, errFinal.name());
    EXPECT_EQ(message, errFinal.description());
    EXPECT_EQ(what, errFinal.what());

    sd_bus_error_free(&error);
}

TEST(SdBusError, BasicError)
{
    const std::string name = "org.freedesktop.DBus.Error.Failed";
    const std::string description = "TestCase";
    const std::string prefix = "BasicError";

    sd_bus_error error = SD_BUS_ERROR_NULL;
    sd_bus_error_set(&error, name.c_str(), description.c_str());
    EXPECT_TRUE(sd_bus_error_is_set(&error));
    const char* nameBeforeMove = error.name;
    const int errorVal = sd_bus_error_get_errno(&error);
    SdBusError err(&error, prefix.c_str());

    // We expect a move not copy
    EXPECT_EQ(nameBeforeMove, err.name());

    // The SdBusError should have moved our error so it should be freeable
    EXPECT_FALSE(sd_bus_error_is_set(&error));
    sd_bus_error_free(&error);
    sd_bus_error_free(&error);

    EXPECT_EQ(errorVal, err.get_errno());
    EXPECT_EQ(name, err.name());
    EXPECT_EQ(description, err.description());
    EXPECT_EQ(prefix + ": " + name + ": " + description, err.what());
}

TEST(SdBusError, CatchBaseClassExceptions)
{
    /* test each class in the chain:
     * std::exception
     *   -> sdbusplus::exception::exception
     *     -> sdbusplus::exception::internal_exception
     *       -> sdbusplus::exception::SdBusError
     */
    EXPECT_THROW({ throw SdBusError(-EINVAL, "SdBusError"); }, SdBusError);
    EXPECT_THROW({ throw SdBusError(-EINVAL, "internal_exception"); },
                 sdbusplus::exception::internal_exception);
    EXPECT_THROW({ throw SdBusError(-EINVAL, "exception"); },
                 sdbusplus::exception::exception);
    EXPECT_THROW({ throw SdBusError(-EINVAL, "std::exception"); },
                 std::exception);
}

} // namespace
