#include "app.hpp"
#include "app_singleton.hpp"
#include "async_resp.hpp"
#include "http_request.hpp"
#include "interface.hpp"
#include "macros.hpp"
#include "privileges.hpp"
#include "query.hpp"
#include "registries/privilege_registry.hpp"
#include "utility.hpp"

#include <boost/asio/io_context.hpp>
#include <boost/beast/http/verb.hpp>
#include <nlohmann/json.hpp>

#include <memory>
#include <string_view>

#include <gtest/gtest.h>

namespace redfish_plugin
{

int platform_plugins_called = 0; // NOLINT

void loadPlatformPlugins()
{
    auto callback = [](const crow::Request&,
                       const std::shared_ptr<bmcweb::AsyncResp>&) {
        platform_plugins_called++;
    };

    REDFISH_HANDLER_ADD("/platform_plugins/", boost::beast::http::verb::get,
                        redfish::privileges::getChassis, std::move(callback));
}

int google_plugins_called = 0; // NOLINT

void loadGooglePlugins()
{
    auto callback = [](const crow::Request&,
                       const std::shared_ptr<bmcweb::AsyncResp>&) {
        google_plugins_called++;
    };

    REDFISH_HANDLER_ADD("/google_plugins/", boost::beast::http::verb::get,
                        redfish::privileges::getChassis, std::move(callback));
}

} // namespace redfish_plugin

namespace crow
{
namespace
{

class PluginMacrosTest : public testing::Test
{
  public:
    PluginMacrosTest()
    {
        io = std::make_shared<boost::asio::io_context>();
        app = std::make_unique<crow::App>(/*allowSessionEmpty=*/true, io);
        crow::globalBmcWebApp = app.get();
    }

  private:
    std::shared_ptr<boost::asio::io_context> io;
    std::unique_ptr<crow::App> app;
};

TEST_F(PluginMacrosTest, AddedHandlerCanBeInvoked)
{
    int called = 0;
    auto callback = [&called](const Request&,
                              const std::shared_ptr<bmcweb::AsyncResp>&) {
        called++;
    };

    REDFISH_HANDLER_ADD("/hello/", boost::beast::http::verb::get,
                        redfish::privileges::getChassis, std::move(callback));

    crow::globalBmcWebApp->validate();

    constexpr std::string_view url = "/hello/";
    std::error_code ec;
    Request req{{boost::beast::http::verb::get, url, 11}, ec};

    auto asyncResp = std::make_shared<bmcweb::AsyncResp>();
    crow::globalBmcWebApp->handle(req, asyncResp);

    EXPECT_EQ(called, 1);
}

#ifdef PLATFORM_PLUGINS_ENABLED
TEST_F(PluginMacrosTest, AddedRedfishResourceHandlerCanBeInvoked)
{
    crow::Logger::setLogLevel(crow::LogLevel::Debug);

    int called_generic = 0;
    BMCWEB_ROUTE((*crow::globalBmcWebApp),
                 "/redfish/v1/UpdateService/FirmwareInventory/<str>/")
        .privileges(redfish::privileges::getSoftwareInventory)
        .methods(boost::beast::http::verb::get)(
            [&called_generic](
                const crow::Request& reqIn,
                const std::shared_ptr<bmcweb::AsyncResp>& asyncRespIn,
                const std::string& param) {
        called_generic++;
        std::shared_ptr<std::string> swId =
            std::make_shared<std::string>(param);

        asyncRespIn->res.jsonValue["@odata.id"] = crow::utility::urlFromPieces(
            "redfish", "v1", "UpdateService", "FirmwareInventory", *swId);
        BMCWEB_LOG_DEBUG << "DEBUG: Inside generic FW ROUTE for " << *swId;
        BMCWEB_LOG_DEBUG << "DEBUG: req method is: " << reqIn.methodString();
    });

    int called_404 = 0;
    BMCWEB_ROUTE((*crow::globalBmcWebApp), "/redfish/<path>")
        .methodNotAllowed()
        .privileges(redfish::privileges::privilegeSetLogin)(
            [&called_404](const crow::Request& reqIn,
                          const std::shared_ptr<bmcweb::AsyncResp>& asyncRespIn,
                          const std::string& path) {
        called_404++;
        asyncRespIn->res.jsonValue["@odata.id"] =
            crow::utility::urlFromPieces("redfish", "v1", path);
        BMCWEB_LOG_DEBUG << "DEBUG: req method for 404 is: "
                         << reqIn.methodString();
    });

    int called = 0;
    auto callback = [&called](const Request&,
                              const std::shared_ptr<bmcweb::AsyncResp>&) {
        called++;
    };

    REDFISH_HANDLER_ADD(
        "/redfish/v1/UpdateService/FirmwareInventory/SpecialFW/",
        boost::beast::http::verb::get,
        redfish::privileges::getSoftwareInventory, std::move(callback));

    crow::globalBmcWebApp->validate();

    constexpr std::string_view url =
        "/redfish/v1/UpdateService/FirmwareInventory/SpecialFW";
    std::error_code ec;
    Request req{{boost::beast::http::verb::get, url, 11}, ec};

    auto asyncResp = std::make_shared<bmcweb::AsyncResp>();
    crow::globalBmcWebApp->handle(req, asyncResp);
    crow::globalBmcWebApp->handle(req, asyncResp);
    crow::globalBmcWebApp->handle(req, asyncResp);

    EXPECT_EQ(called, 3);
    EXPECT_EQ(called_generic, 0);
    EXPECT_EQ(called_404, 0);

    constexpr std::string_view url2 =
        "/redfish/v1/UpdateService/FirmwareInventory/foo";
    std::error_code ec2;
    Request req2{{boost::beast::http::verb::get, url2, 11}, ec2};
    auto asyncResp2 = std::make_shared<bmcweb::AsyncResp>();
    crow::globalBmcWebApp->handle(req2, asyncResp2);
    crow::globalBmcWebApp->handle(req2, asyncResp2);
    crow::globalBmcWebApp->handle(req2, asyncResp2);
    crow::globalBmcWebApp->handle(req2, asyncResp2);
    crow::globalBmcWebApp->handle(req2, asyncResp2);

    EXPECT_EQ(called, 3);
    EXPECT_EQ(called_generic, 5);
    EXPECT_EQ(called_404, 0);
}
#endif

TEST_F(PluginMacrosTest, DuplicateHandlerThrows)
{
    auto callback = [](const Request&,
                       const std::shared_ptr<bmcweb::AsyncResp>&) {};

    REDFISH_HANDLER_ADD("/hello/", boost::beast::http::verb::get,
                        redfish::privileges::getChassis, callback);
    REDFISH_HANDLER_ADD("/hello/", boost::beast::http::verb::get,
                        redfish::privileges::getChassis, std::move(callback));

    EXPECT_ANY_THROW(crow::globalBmcWebApp->validate());
}

TEST_F(PluginMacrosTest, ReplacedNonExistHandlerThrows)
{
    auto callback = [](const Request&,
                       const std::shared_ptr<bmcweb::AsyncResp>&) {};
    EXPECT_ANY_THROW(REDFISH_HANDLER_REPLACE("/hello/",
                                             boost::beast::http::verb::get,
                                             std::move(callback)););
}

TEST_F(PluginMacrosTest, ReplacedHandlerCanBeInvoked)
{
    int originalCalled = 0;
    auto originalCallback =
        [&originalCalled](const Request&,
                          const std::shared_ptr<bmcweb::AsyncResp>&) {
        originalCalled++;
    };

    int replacedCalled = 0;
    auto replacedCallback =
        [&replacedCalled](const Request&,
                          const std::shared_ptr<bmcweb::AsyncResp>&) {
        replacedCalled++;
    };

    REDFISH_HANDLER_ADD("/hello/", boost::beast::http::verb::get,
                        redfish::privileges::getChassis,
                        std::move(originalCallback));
    REDFISH_HANDLER_REPLACE("/hello/", boost::beast::http::verb::get,
                            std::move(replacedCallback));
    crow::globalBmcWebApp->validate();

    constexpr std::string_view url = "/hello/";
    std::error_code ec;
    Request req{{boost::beast::http::verb::get, url, 11}, ec};

    auto asyncResp = std::make_shared<bmcweb::AsyncResp>();
    crow::globalBmcWebApp->handle(req, asyncResp);

    EXPECT_EQ(originalCalled, 0);
    EXPECT_EQ(replacedCalled, 1);
}

TEST_F(PluginMacrosTest, RemoveNonExistHandlerThrows)
{
    EXPECT_ANY_THROW(
        REDFISH_HANDLER_REMOVE("/hello/", boost::beast::http::verb::get));
}

TEST_F(PluginMacrosTest, RemovedHandlerNotBeInvoked)
{
    int originalCalled = 0;
    auto originalCallback =
        [&originalCalled](const Request&,
                          const std::shared_ptr<bmcweb::AsyncResp>&) {
        originalCalled++;
    };

    REDFISH_HANDLER_ADD("/hello/", boost::beast::http::verb::get,
                        redfish::privileges::getChassis,
                        std::move(originalCallback));
    REDFISH_HANDLER_REMOVE("/hello/", boost::beast::http::verb::get);
    crow::globalBmcWebApp->validate();

    constexpr std::string_view url = "/hello/";
    std::error_code ec;
    Request req{{boost::beast::http::verb::get, url, 11}, ec};

    auto asyncResp = std::make_shared<bmcweb::AsyncResp>();
    crow::globalBmcWebApp->handle(req, asyncResp);

    EXPECT_EQ(originalCalled, 0);
}

TEST_F(PluginMacrosTest, AppendNonExistHandlerThrows)
{
    auto callback = [](const Request&,
                       const std::shared_ptr<bmcweb::AsyncResp>&) {};

    EXPECT_ANY_THROW(REDFISH_HANDLER_APPEND(
        "/hello/", boost::beast::http::verb::get, std::move(callback)));
}

TEST_F(PluginMacrosTest, AppendRemovedHandlerThrows)
{
    int originalCalled = 0;
    auto originalCallback =
        [&originalCalled](const Request&,
                          const std::shared_ptr<bmcweb::AsyncResp>&) {
        originalCalled++;
    };
    int appendedCalled = 0;
    auto appendedCallback =
        [&appendedCalled](const Request&,
                          const std::shared_ptr<bmcweb::AsyncResp>&) {
        appendedCalled++;
    };
    REDFISH_HANDLER_ADD("/hello/", boost::beast::http::verb::get,
                        redfish::privileges::getChassis,
                        std::move(originalCallback));
    REDFISH_HANDLER_APPEND("/hello/", boost::beast::http::verb::get,
                           std::move(appendedCallback));
    REDFISH_HANDLER_REMOVE("/hello/", boost::beast::http::verb::get);

    constexpr std::string_view url = "/hello/";
    std::error_code ec;
    Request req{{boost::beast::http::verb::get, url, 11}, ec};

    auto asyncResp = std::make_shared<bmcweb::AsyncResp>();
    crow::globalBmcWebApp->handle(req, asyncResp);

    EXPECT_EQ(originalCalled, 0);
    EXPECT_EQ(appendedCalled, 0);
}

TEST_F(PluginMacrosTest, AppendedHandlerCanBeCompletelyRemoved)
{
    auto callback = [](const Request&,
                       const std::shared_ptr<bmcweb::AsyncResp>&) {};
    REDFISH_HANDLER_ADD("/hello/", boost::beast::http::verb::get,
                        redfish::privileges::getChassis, callback);
    REDFISH_HANDLER_REMOVE("/hello/", boost::beast::http::verb::get);
    EXPECT_ANY_THROW(REDFISH_HANDLER_APPEND(
        "/hello/", boost::beast::http::verb::get, std::move(callback)));
}

TEST_F(PluginMacrosTest, ReplacedHandlerCanBeAppended)
{

    int replacedCalled = 0;
    auto replacedCallback =
        [&replacedCalled](const Request& req,
                          const std::shared_ptr<bmcweb::AsyncResp>& resp) {
        EXPECT_TRUE(redfish::setUpRedfishRouteOnGlobalApp(req, resp));
        replacedCalled++;
    };

    int appendedCalled = 0;
    auto appendedCallback =
        [&appendedCalled](const Request&,
                          const std::shared_ptr<bmcweb::AsyncResp>&) {
        appendedCalled++;
    };

    REDFISH_HANDLER_ADD(
        "/hello/", boost::beast::http::verb::get,
        redfish::privileges::getChassis,
        [](const Request&, const std::shared_ptr<bmcweb::AsyncResp>&) {});
    REDFISH_HANDLER_REPLACE("/hello/", boost::beast::http::verb::get,
                            std::move(replacedCallback));
    REDFISH_HANDLER_APPEND("/hello/", boost::beast::http::verb::get,
                           std::move(appendedCallback));
    crow::globalBmcWebApp->validate();

    constexpr std::string_view url = "/hello/";
    std::error_code ec;
    Request req{{boost::beast::http::verb::get, url, 11}, ec};

    // This is to make sure |asyncResp| destructs
    {
        auto asyncResp = std::make_shared<bmcweb::AsyncResp>();
        crow::globalBmcWebApp->handle(req, asyncResp);
    }

    EXPECT_EQ(appendedCalled, 1);
    EXPECT_EQ(replacedCalled, 1);
}

// The test makes sure the execution order is:
// 1. originalCallback
// 2. appendedCallback (if multiple appends exist, the order is LIFO; please
// note multiple appends should be rarely used)
// 3. callback setup by setUpRedfishRoute
TEST_F(PluginMacrosTest, AppendedHandlerBeInvokedInOrder)
{
    crow::Logger::setLogLevel(crow::LogLevel::Debug);

    int originalCalled = 0;
    int appendedOneCalled = 0;
    int appendedTwoCalled = 0;
    int onlyCalled = 0;
    auto originalCallback =
        [&originalCalled, &appendedOneCalled, &appendedTwoCalled,
         &onlyCalled](const Request& req,
                      const std::shared_ptr<bmcweb::AsyncResp>& resp) {
        EXPECT_TRUE(redfish::setUpRedfishRouteOnGlobalApp(req, resp));
        EXPECT_EQ(appendedOneCalled, 0);
        EXPECT_EQ(appendedTwoCalled, 0);
        EXPECT_EQ(onlyCalled, 0);
        originalCalled++;
        resp->res.jsonValue = R"(
{
  "Members": [
    {
      "@odata.id": "/only"
    }
  ]
}
)"_json;
    };

    auto appendedOneCallback =
        [&originalCalled, &appendedOneCalled, &appendedTwoCalled, &onlyCalled](
            const Request&, const std::shared_ptr<bmcweb::AsyncResp>&) {
        EXPECT_EQ(originalCalled, 1);
        // this tests that the callback setup by setUpRedfishRoute hasn't run
        EXPECT_EQ(onlyCalled, 0);
        // the order is LIFO
        EXPECT_EQ(appendedTwoCalled, 1);
        appendedOneCalled++;
    };

    auto appendedTwoCallback =
        [&originalCalled, &appendedOneCalled, &appendedTwoCalled, &onlyCalled](
            const Request&, const std::shared_ptr<bmcweb::AsyncResp>&) {
        EXPECT_EQ(originalCalled, 1);
        // this tests that the callback setup by setUpRedfishRoute hasn't run
        EXPECT_EQ(onlyCalled, 0);
        EXPECT_EQ(appendedOneCalled, 0);
        appendedTwoCalled++;
    };

    auto onlyCallback =
        [&originalCalled, &appendedOneCalled, &appendedTwoCalled, &onlyCalled](
            const Request&, const std::shared_ptr<bmcweb::AsyncResp>&) {
        EXPECT_TRUE(originalCalled);
        EXPECT_TRUE(appendedOneCalled);
        EXPECT_TRUE(appendedTwoCalled);
        onlyCalled = 1;
    };

    REDFISH_HANDLER_ADD("/hello/", boost::beast::http::verb::get,
                        redfish::privileges::getChassis,
                        std::move(originalCallback));
    REDFISH_HANDLER_ADD("/only", boost::beast::http::verb::get,
                        redfish::privileges::getChassis,
                        std::move(onlyCallback));
    REDFISH_HANDLER_APPEND("/hello/", boost::beast::http::verb::get,
                           std::move(appendedOneCallback));
    REDFISH_HANDLER_APPEND("/hello/", boost::beast::http::verb::get,
                           std::move(appendedTwoCallback));
    crow::globalBmcWebApp->validate();

    constexpr std::string_view url = "/hello/?only";
    std::error_code ec;
    Request req{{boost::beast::http::verb::get, url, 11}, ec};

    // This is to make sure |asyncResp| destructs
    {
        auto asyncResp = std::make_shared<bmcweb::AsyncResp>();
        asyncResp->res.setCompleteRequestHandler([](crow::Response&) {});
        crow::globalBmcWebApp->handle(req, asyncResp);
    }

    EXPECT_EQ(onlyCalled, 1);
}

TEST_F(PluginMacrosTest, AppendedHandlerGetsParams)
{
    auto originalCallback = [](const Request& req,
                               const std::shared_ptr<bmcweb::AsyncResp>& resp,
                               const std::string&) {
        EXPECT_TRUE(redfish::setUpRedfishRouteOnGlobalApp(req, resp));
    };

    int appendedCalled = 0;
    auto appendedCallback =
        [&appendedCalled](const Request&,
                          const std::shared_ptr<bmcweb::AsyncResp>&,
                          const std::string& param) {
        EXPECT_EQ(param, "awesome");
        appendedCalled++;
    };

    REDFISH_HANDLER_ADD("/hello/<str>/", boost::beast::http::verb::get,
                        redfish::privileges::getChassis,
                        std::move(originalCallback));
    REDFISH_HANDLER_APPEND("/hello/<str>/", boost::beast::http::verb::get,
                           std::move(appendedCallback));
    crow::globalBmcWebApp->validate();

    constexpr std::string_view url = "/hello/awesome/";
    std::error_code ec;
    Request req{{boost::beast::http::verb::get, url, 11}, ec};

    // This is to make sure |asyncResp| destructs
    {
        auto asyncResp = std::make_shared<bmcweb::AsyncResp>();
        asyncResp->res.setCompleteRequestHandler([](crow::Response&) {});
        crow::globalBmcWebApp->handle(req, asyncResp);
    }

    EXPECT_EQ(appendedCalled, 1);
}

// Every Redfish Route is suppose to have Redfish parameter handler; however,
// plugin code shouldn't fail if a Redfish route is not configured properly.
// This test ensures that scenario.
TEST_F(PluginMacrosTest, AppendedHandlerRunsWithoutRedfishParamsHandler)
{
    auto originalCallback = [](const Request&,
                               const std::shared_ptr<bmcweb::AsyncResp>&) {};

    int appendedCalled = 0;
    auto appendedCallback =
        [&appendedCalled](const Request&,
                          const std::shared_ptr<bmcweb::AsyncResp>&) {
        appendedCalled++;
    };

    REDFISH_HANDLER_ADD("/hello/", boost::beast::http::verb::get,
                        redfish::privileges::getChassis,
                        std::move(originalCallback));
    REDFISH_HANDLER_APPEND("/hello/", boost::beast::http::verb::get,
                           std::move(appendedCallback));
    crow::globalBmcWebApp->validate();

    constexpr std::string_view url = "/hello/";
    std::error_code ec;
    Request req{{boost::beast::http::verb::get, url, 11}, ec};

    // This is to make sure |asyncResp| destructs
    {
        auto asyncResp = std::make_shared<bmcweb::AsyncResp>();
        asyncResp->res.setCompleteRequestHandler([](crow::Response&) {});
        crow::globalBmcWebApp->handle(req, asyncResp);
    }

    EXPECT_EQ(appendedCalled, 1);
}

TEST_F(PluginMacrosTest, AddHandlerWorksWithArbitraryLayerOfPlugins)
{
    redfish_plugin::loadPlatformPlugins();
    redfish_plugin::loadGooglePlugins();

    crow::globalBmcWebApp->validate();

    std::error_code ec;
    Request req1{{boost::beast::http::verb::get, "/platform_plugins/", 11}, ec};

    auto asyncResp1 = std::make_shared<bmcweb::AsyncResp>();
    crow::globalBmcWebApp->handle(req1, asyncResp1);

    Request req2{{boost::beast::http::verb::get, "/google_plugins/", 11}, ec};

    auto asyncResp2 = std::make_shared<bmcweb::AsyncResp>();
    crow::globalBmcWebApp->handle(req2, asyncResp2);

    EXPECT_EQ(redfish_plugin::platform_plugins_called, 1);
    EXPECT_EQ(redfish_plugin::google_plugins_called, 1);
}

TEST_F(PluginMacrosTest, AppendHandlerCanGetDelegateExpandLevelOfQuery)
{
    constexpr int expandLevelInGenericHandler = 6;
    BMCWEB_ROUTE((*crow::globalBmcWebApp),
                 "/redfish/v1/Systems/system/Processors/")
        .privileges(redfish::privileges::headProcessorCollection)
        .methods(boost::beast::http::verb::get)(
            [](const crow::Request&,
               const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) {
        asyncResp->delegatedExpandLevel = expandLevelInGenericHandler;
    });

    int delegatedExpandLevelInAppendHandler = 0;
    auto appendedCallback =
        [&delegatedExpandLevelInAppendHandler](
            const Request&,
            const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) {
        delegatedExpandLevelInAppendHandler = asyncResp->delegatedExpandLevel;
    };

    REDFISH_HANDLER_APPEND("/redfish/v1/Systems/system/Processors/",
                           boost::beast::http::verb::get,
                           std::move(appendedCallback));
    crow::globalBmcWebApp->validate();

    constexpr std::string_view url = "/redfish/v1/Systems/system/Processors/";
    std::error_code ec;
    Request req{{boost::beast::http::verb::get, url, 11}, ec};

    // This is to make sure |asyncResp| destructs
    {
        auto asyncResp = std::make_shared<bmcweb::AsyncResp>();
        asyncResp->res.setCompleteRequestHandler([](crow::Response&) {});
        crow::globalBmcWebApp->handle(req, asyncResp);
    }

    EXPECT_EQ(delegatedExpandLevelInAppendHandler, expandLevelInGenericHandler);
}

TEST_F(PluginMacrosTest, AppendHandlerCaptureByReferenceCheck)
{
    // check the safety of pass by copy for callback handler
    boost::asio::io_context io;

    auto originalCallback =
        [&io](const Request& req, const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) {

        boost::asio::post(io, [asyncResp](){
            BMCWEB_LOG_DEBUG << "Delay the call \n";
        });

        EXPECT_EQ(req.target(), "/hello");
    };

   auto appendedCallback =
        [](const Request& req, const std::shared_ptr<bmcweb::AsyncResp>&) {
        EXPECT_EQ(req.target(), "/hello");
   };

    REDFISH_HANDLER_ADD("/hello/", boost::beast::http::verb::get,
                       redfish::privileges::getChassis,
                       std::move(originalCallback));
    REDFISH_HANDLER_APPEND("/hello/", boost::beast::http::verb::get,
                          std::move(appendedCallback));

    crow::globalBmcWebApp->validate();

    constexpr std::string_view url = "/hello";
    std::error_code ec;

    // This is to make sure |asyncResp| destructs
    {
        Request req{{boost::beast::http::verb::get, url, 11}, ec};

        auto asyncResp = std::make_shared<bmcweb::AsyncResp>();
        asyncResp->res.setCompleteRequestHandler(
            [](crow::Response&) {}
        );
        crow::globalBmcWebApp->handle(req, asyncResp);
    }
    io.run_one();
}

} // namespace
} // namespace crow
