#include <systemd/sd-bus.h>

#include <cstdlib>
#include <sdbusplus/exception.hpp>
#include <sdbusplus/test/sdbus_mock.hpp>
#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
