#include "dbus_environment.hpp"
#include "helpers.hpp"
#include "mocks/json_storage_mock.hpp"
#include "mocks/trigger_factory_mock.hpp"
#include "mocks/trigger_mock.hpp"
#include "params/trigger_params.hpp"
#include "trigger.hpp"
#include "trigger_manager.hpp"
#include "utils/conversion_trigger.hpp"
#include "utils/transform.hpp"

using namespace testing;
using sdbusplus::message::object_path;

class TestTriggerManager : public Test
{
  public:
    std::pair<boost::system::error_code, std::string>
        addTrigger(const TriggerParams& params)
    {
        const auto sensorInfos =
            utils::fromLabeledSensorsInfo(params.sensors());

        std::promise<std::pair<boost::system::error_code, std::string>>
            addTriggerPromise;
        DbusEnvironment::getBus()->async_method_call(
            [&addTriggerPromise](boost::system::error_code ec,
                                 const std::string& path) {
                addTriggerPromise.set_value({ec, path});
            },
            DbusEnvironment::serviceName(), TriggerManager::triggerManagerPath,
            TriggerManager::triggerManagerIfaceName, "AddTrigger", params.id(),
            params.name(),
            utils::transform(
                params.triggerActions(),
                [](const auto& action) { return actionToString(action); }),
            sensorInfos, params.reports(),
            std::visit(utils::FromLabeledThresholdParamConversion(),
                       params.thresholdParams()));
        return DbusEnvironment::waitForFuture(addTriggerPromise.get_future());
    }

    std::unique_ptr<TriggerManager> makeTriggerManager()
    {
        return std::make_unique<TriggerManager>(
            std::move(triggerFactoryMockPtr), std::move(storageMockPtr),
            DbusEnvironment::getObjServer());
    }

    void SetUp() override
    {
        sut = makeTriggerManager();
    }

    std::unique_ptr<StorageMock> storageMockPtr =
        std::make_unique<NiceMock<StorageMock>>();
    StorageMock& storageMock = *storageMockPtr;
    std::unique_ptr<TriggerFactoryMock> triggerFactoryMockPtr =
        std::make_unique<NiceMock<TriggerFactoryMock>>();
    TriggerFactoryMock& triggerFactoryMock = *triggerFactoryMockPtr;
    std::unique_ptr<TriggerMock> triggerMockPtr =
        std::make_unique<NiceMock<TriggerMock>>(TriggerParams().id());
    TriggerMock& triggerMock = *triggerMockPtr;
    std::unique_ptr<TriggerManager> sut;
    MockFunction<void(std::string)> checkPoint;
};

TEST_F(TestTriggerManager, addTrigger)
{
    triggerFactoryMock.expectMake(TriggerParams(), Ref(*sut), Ref(storageMock))
        .WillOnce(Return(ByMove(std::move(triggerMockPtr))));

    auto [ec, path] = addTrigger(TriggerParams());
    EXPECT_THAT(ec.value(), Eq(boost::system::errc::success));
    EXPECT_THAT(path, Eq(triggerMock.getPath()));
}

TEST_F(TestTriggerManager, addTriggerWithDiscreteThresholds)
{
    TriggerParams triggerParamsDiscrete;
    auto thresholds = std::vector<discrete::LabeledThresholdParam>{
        {"discrete_threshold1", discrete::Severity::ok, 10, "11.0"},
        {"discrete_threshold2", discrete::Severity::warning, 10, "12.0"},
        {"discrete_threshold3", discrete::Severity::critical, 10, "13.0"}};

    triggerParamsDiscrete.thresholdParams(thresholds);

    auto [ec, path] = addTrigger(triggerParamsDiscrete);
    EXPECT_THAT(ec.value(), Eq(boost::system::errc::success));
    EXPECT_THAT(path, Eq(triggerMock.getPath()));
}

TEST_F(TestTriggerManager, addDiscreteTriggerWithoutThresholds)
{
    TriggerParams triggerParamsDiscrete;
    auto thresholds = std::vector<discrete::LabeledThresholdParam>();

    triggerParamsDiscrete.thresholdParams(thresholds);

    auto [ec, path] = addTrigger(triggerParamsDiscrete);
    EXPECT_THAT(ec.value(), Eq(boost::system::errc::success));
    EXPECT_THAT(path, Eq(triggerMock.getPath()));
}

TEST_F(TestTriggerManager, DISABLED_failToAddTriggerTwice)
{
    triggerFactoryMock.expectMake(TriggerParams(), Ref(*sut), Ref(storageMock))
        .WillOnce(Return(ByMove(std::move(triggerMockPtr))));

    addTrigger(TriggerParams());

    auto [ec, path] = addTrigger(TriggerParams());
    EXPECT_THAT(ec.value(), Eq(boost::system::errc::file_exists));
    EXPECT_THAT(path, Eq(std::string()));
}

TEST_F(TestTriggerManager, DISABLED_failToAddTriggerWithInvalidId)
{
    triggerFactoryMock.expectMake(std::nullopt, Ref(*sut), Ref(storageMock))
        .Times(0);

    auto [ec, path] = addTrigger(TriggerParams().id("not valid?"));
    EXPECT_THAT(ec.value(), Eq(boost::system::errc::invalid_argument));
    EXPECT_THAT(path, Eq(std::string()));
}

TEST_F(TestTriggerManager, DISABLED_failToAddTriggerWithDuplicatesInReportsIds)
{
    triggerFactoryMock.expectMake(std::nullopt, Ref(*sut), Ref(storageMock))
        .Times(0);

    auto [ec, path] = addTrigger(
        TriggerParams().reportIds({"trigger1", "trigger2", "trigger1"}));
    EXPECT_THAT(ec.value(), Eq(boost::system::errc::invalid_argument));
    EXPECT_THAT(path, Eq(std::string()));
}

TEST_F(TestTriggerManager, addTriggerWithProperReportPaths)
{
    auto [ec, path] = addTrigger(TriggerParams().reports(
        {object_path("/xyz/openbmc_project/Telemetry/Reports/MyReport"),
         object_path(
             "/xyz/openbmc_project/Telemetry/Reports/MyPrefix/MyReport")}));
    EXPECT_THAT(ec.value(), Eq(boost::system::errc::success));
    EXPECT_THAT(path, Eq(triggerMock.getPath()));
}

TEST_F(TestTriggerManager, DISABLED_failToAddTriggerWithBadReportsPath)
{
    triggerFactoryMock.expectMake(std::nullopt, Ref(*sut), Ref(storageMock))
        .Times(0);

    auto [ec, path] = addTrigger(TriggerParams().reports(
        {object_path("/xyz/openbmc_project/Telemetry/NotReports/MyReport")}));
    EXPECT_THAT(ec.value(), Eq(boost::system::errc::invalid_argument));
    EXPECT_THAT(path, Eq(std::string()));
}

TEST_F(TestTriggerManager, DISABLED_failToAddTriggerWithTooManyReportPrefixes)
{
    triggerFactoryMock.expectMake(std::nullopt, Ref(*sut), Ref(storageMock))
        .Times(0);

    auto [ec, path] = addTrigger(TriggerParams().reports({object_path(
        "/xyz/openbmc_project/Telemetry/Reports/P1/P2/MyReport")}));
    EXPECT_THAT(ec.value(), Eq(boost::system::errc::invalid_argument));
    EXPECT_THAT(path, Eq(std::string()));
}

TEST_F(TestTriggerManager, addTriggerWithoutIdAndName)
{
    triggerFactoryMock
        .expectMake(TriggerParams()
                        .id(TriggerManager::triggerNameDefault)
                        .name(TriggerManager::triggerNameDefault),
                    Ref(*sut), Ref(storageMock))
        .WillOnce(Return(ByMove(std::move(triggerMockPtr))));

    auto [ec, path] = addTrigger(TriggerParams().id("").name(""));
    EXPECT_THAT(ec.value(), Eq(boost::system::errc::success));
    EXPECT_THAT(path, Not(Eq("")));
}

TEST_F(TestTriggerManager, addTriggerWithPrefixId)
{
    triggerFactoryMock
        .expectMake(TriggerParams()
                        .id("TelemetryService/HackyName")
                        .name("Hacky/Name!@#$"),
                    Ref(*sut), Ref(storageMock))
        .WillOnce(Return(ByMove(std::move(triggerMockPtr))));

    auto [ec, path] = addTrigger(
        TriggerParams().id("TelemetryService/").name("Hacky/Name!@#$"));
    EXPECT_THAT(ec.value(), Eq(boost::system::errc::success));
    EXPECT_THAT(path, Not(Eq("")));
}

TEST_F(TestTriggerManager, addTriggerWithoutIdTwice)
{
    addTrigger(TriggerParams().id(""));

    auto [ec, path] = addTrigger(TriggerParams().id(""));
    EXPECT_THAT(ec.value(), Eq(boost::system::errc::success));
    EXPECT_THAT(path, Not(Eq("")));
}

TEST_F(TestTriggerManager, addTriggerWithoutIdAndWithLongNameTwice)
{
    addTrigger(TriggerParams().id("").name(
        std::string(2 * TriggerManager::maxTriggerIdLength, 'z')));

    auto [ec, path] = addTrigger(TriggerParams().id("").name(
        std::string(2 * TriggerManager::maxTriggerIdLength, 'z')));
    EXPECT_THAT(ec.value(), Eq(boost::system::errc::success));
    EXPECT_THAT(path, Not(Eq("")));
}

TEST_F(TestTriggerManager, addTriggerWithMaxLengthId)
{
    auto triggerId = std::string(TriggerManager::maxTriggerIdLength, 'z');
    auto triggerParams = TriggerParams().id(triggerId);

    triggerFactoryMock.expectMake(triggerParams, Ref(*sut), Ref(storageMock))
        .WillOnce(Return(ByMove(std::move(triggerMockPtr))));

    auto [ec, path] = addTrigger(triggerParams);

    EXPECT_THAT(ec.value(), Eq(boost::system::errc::success));
    EXPECT_THAT(path, Eq(triggerMock.getPath()));
}

TEST_F(TestTriggerManager, DISABLED_failToAddTriggerWithTooLongId)
{
    auto triggerId = std::string(TriggerManager::maxTriggerIdLength + 1, 'z');
    auto triggerParams = TriggerParams().id(triggerId);

    triggerFactoryMock.expectMake(std::nullopt, Ref(*sut), Ref(storageMock))
        .Times(0);

    auto [ec, path] = addTrigger(triggerParams);

    EXPECT_THAT(ec.value(), Eq(boost::system::errc::invalid_argument));
    EXPECT_THAT(path, Eq(std::string()));
}

TEST_F(TestTriggerManager, DISABLED_failToAddTriggerWhenMaxTriggerIsReached)
{
    auto triggerParams = TriggerParams();

    triggerFactoryMock.expectMake(std::nullopt, Ref(*sut), Ref(storageMock))
        .Times(TriggerManager::maxTriggers);

    for (size_t i = 0; i < TriggerManager::maxTriggers; i++)
    {
        triggerParams.id(TriggerParams().id() + std::to_string(i));

        auto [ec, path] = addTrigger(triggerParams);
        EXPECT_THAT(ec.value(), Eq(boost::system::errc::success));
    }

    triggerParams.id(TriggerParams().id() +
                     std::to_string(TriggerManager::maxTriggers));
    auto [ec, path] = addTrigger(triggerParams);
    EXPECT_THAT(ec.value(), Eq(boost::system::errc::too_many_files_open));
    EXPECT_THAT(path, Eq(std::string()));
}

TEST_F(TestTriggerManager, removeTrigger)
{
    {
        InSequence seq;
        triggerFactoryMock
            .expectMake(TriggerParams(), Ref(*sut), Ref(storageMock))
            .WillOnce(Return(ByMove(std::move(triggerMockPtr))));
        EXPECT_CALL(triggerMock, Die());
        EXPECT_CALL(checkPoint, Call("end"));
    }

    addTrigger(TriggerParams());
    sut->removeTrigger(&triggerMock);
    checkPoint.Call("end");
}

TEST_F(TestTriggerManager, removingTriggerThatIsNotInContainerHasNoEffect)
{
    {
        InSequence seq;
        EXPECT_CALL(checkPoint, Call("end"));
        EXPECT_CALL(triggerMock, Die());
    }

    sut->removeTrigger(&triggerMock);
    checkPoint.Call("end");
}

TEST_F(TestTriggerManager, removingSameTriggerTwiceHasNoSideEffect)
{
    {
        InSequence seq;
        triggerFactoryMock
            .expectMake(TriggerParams(), Ref(*sut), Ref(storageMock))
            .WillOnce(Return(ByMove(std::move(triggerMockPtr))));
        EXPECT_CALL(triggerMock, Die());
        EXPECT_CALL(checkPoint, Call("end"));
    }

    addTrigger(TriggerParams());
    sut->removeTrigger(&triggerMock);
    sut->removeTrigger(&triggerMock);
    checkPoint.Call("end");
}
class TestTriggerManagerStorage : public TestTriggerManager
{
  public:
    using FilePath = interfaces::JsonStorage::FilePath;
    using DirectoryPath = interfaces::JsonStorage::DirectoryPath;

    void SetUp() override
    {
        ON_CALL(storageMock, list())
            .WillByDefault(Return(std::vector<FilePath>{
                {FilePath("trigger1")}, {FilePath("trigger2")}}));

        ON_CALL(storageMock, load(FilePath("trigger1")))
            .WillByDefault(InvokeWithoutArgs([this] { return data1; }));

        data2["Id"] = "Trigger2";
        data2["Name"] = "Second Trigger";
        ON_CALL(storageMock, load(FilePath("trigger2")))
            .WillByDefault(InvokeWithoutArgs([this] { return data2; }));
    }

    nlohmann::json data1 = nlohmann::json{
        {"Version", Trigger::triggerVersion},
        {"Id", TriggerParams().id()},
        {"Name", TriggerParams().name()},
        {"ThresholdParamsDiscriminator",
         TriggerParams().thresholdParams().index()},
        {"TriggerActions", utils::transform(TriggerParams().triggerActions(),
                                            [](const auto& action) {
                                                return actionToString(action);
                                            })},
        {"ThresholdParams", utils::labeledThresholdParamsToJson(
                                TriggerParams().thresholdParams())},
        {"ReportIds", TriggerParams().reportIds()},
        {"Sensors", TriggerParams().sensors()}};

    nlohmann::json data2 = data1;
};

TEST_F(TestTriggerManagerStorage, triggerManagerCtorAddTriggerFromStorage)
{
    triggerFactoryMock.expectMake(TriggerParams(), _, Ref(storageMock));
    triggerFactoryMock.expectMake(
        TriggerParams().id("Trigger2").name("Second Trigger"), _,
        Ref(storageMock));
    EXPECT_CALL(storageMock, remove(_)).Times(0);

    sut = makeTriggerManager();
}

TEST_F(TestTriggerManagerStorage,
       triggerManagerCtorRemoveDiscreteTriggerFromStorage)
{
    LabeledTriggerThresholdParams thresholdParams =
        std::vector<discrete::LabeledThresholdParam>{
            {"userId1", discrete::Severity::warning, 15, "10.0"},
            {"userId2", discrete::Severity::critical, 5, "20.0"}};

    data1["ThresholdParamsDiscriminator"] = thresholdParams.index();

    data1["ThresholdParams"] =
        utils::labeledThresholdParamsToJson(thresholdParams);

    EXPECT_CALL(storageMock, remove(FilePath("trigger1"))).Times(0);

    sut = makeTriggerManager();
}

TEST_F(TestTriggerManagerStorage,
       triggerManagerCtorRemoveDiscreteTriggerFromStorage2)
{
    data1["IsDiscrete"] = true;

    EXPECT_CALL(storageMock, remove(FilePath("trigger1"))).Times(0);

    sut = makeTriggerManager();
}

TEST_F(TestTriggerManagerStorage,
       triggerManagerCtorAddProperRemoveInvalidTriggerFromStorage)
{
    data1["Version"] = Trigger::triggerVersion - 1;

    triggerFactoryMock.expectMake(
        TriggerParams().id("Trigger2").name("Second Trigger"), _,
        Ref(storageMock));
    EXPECT_CALL(storageMock, remove(FilePath("trigger1")));

    sut = makeTriggerManager();
}
