#include "dbus_environment.hpp"
#include "helpers.hpp"
#include "messages/collect_trigger_id.hpp"
#include "messages/trigger_presence_changed_ind.hpp"
#include "mocks/json_storage_mock.hpp"
#include "mocks/report_manager_mock.hpp"
#include "mocks/sensor_mock.hpp"
#include "mocks/threshold_mock.hpp"
#include "mocks/trigger_factory_mock.hpp"
#include "mocks/trigger_manager_mock.hpp"
#include "params/trigger_params.hpp"
#include "trigger.hpp"
#include "trigger_manager.hpp"
#include "utils/conversion_trigger.hpp"
#include "utils/dbus_path_utils.hpp"
#include "utils/messanger.hpp"
#include "utils/string_utils.hpp"
#include "utils/transform.hpp"
#include "utils/tstring.hpp"

#include <boost/range/combine.hpp>

using namespace testing;
using namespace std::literals::string_literals;
using sdbusplus::message::object_path;

static constexpr size_t expectedTriggerVersion = 2;

class TestTrigger : public Test
{
  public:
    TriggerParams triggerParams;
    TriggerParams triggerDiscreteParams =
        TriggerParams()
            .id("DiscreteTrigger")
            .name("My Discrete Trigger")
            .thresholdParams(std::vector<discrete::LabeledThresholdParam>{
                discrete::LabeledThresholdParam{
                    "userId", discrete::Severity::warning,
                    Milliseconds(10).count(), "15.2"},
                discrete::LabeledThresholdParam{
                    "userId_2", discrete::Severity::critical,
                    Milliseconds(5).count(), "32.7"},
            });

    std::unique_ptr<ReportManagerMock> reportManagerMockPtr =
        std::make_unique<NiceMock<ReportManagerMock>>();
    std::unique_ptr<TriggerManagerMock> triggerManagerMockPtr =
        std::make_unique<NiceMock<TriggerManagerMock>>();
    std::unique_ptr<TriggerFactoryMock> triggerFactoryMockPtr =
        std::make_unique<NiceMock<TriggerFactoryMock>>();
    testing::NiceMock<StorageMock> storageMock;
    NiceMock<MockFunction<void(const messages::TriggerPresenceChangedInd)>>
        triggerPresenceChanged;
    std::vector<std::shared_ptr<interfaces::Threshold>> thresholdMocks;
    utils::Messanger messanger;
    std::unique_ptr<Trigger> sut;

    TestTrigger() : messanger(DbusEnvironment::getIoc())
    {
        messanger.on_receive<messages::TriggerPresenceChangedInd>(
            [this](const auto& msg) { triggerPresenceChanged.Call(msg); });
    }

    void SetUp() override
    {
        sut = makeTrigger(triggerParams);
    }

    static std::vector<LabeledSensorInfo>
        convertToLabeledSensor(const SensorsInfo& sensorsInfo)
    {
        return utils::transform(sensorsInfo, [](const auto& sensorInfo) {
            const auto& [sensorPath, sensorMetadata] = sensorInfo;
            return LabeledSensorInfo("service1", sensorPath, sensorMetadata);
        });
    }

    std::unique_ptr<Trigger> makeTrigger(const TriggerParams& params)
    {
        thresholdMocks =
            ThresholdMock::makeThresholds(params.thresholdParams());

        auto id = std::make_unique<const std::string>(params.id());

        return std::make_unique<Trigger>(
            DbusEnvironment::getIoc(), DbusEnvironment::getObjServer(),
            std::move(id), params.name(), params.triggerActions(),
            std::make_shared<std::vector<std::string>>(
                params.reportIds().begin(), params.reportIds().end()),
            std::vector<std::shared_ptr<interfaces::Threshold>>(thresholdMocks),
            *triggerManagerMockPtr, storageMock, *triggerFactoryMockPtr,
            SensorMock::makeSensorMocks(params.sensors()));
    }

    static interfaces::JsonStorage::FilePath to_file_path(std::string name)
    {
        return interfaces::JsonStorage::FilePath(
            std::to_string(std::hash<std::string>{}(name)));
    }

    template <class T>
    static T getProperty(const std::string& path, const std::string& property)
    {
        return DbusEnvironment::getProperty<T>(path, Trigger::triggerIfaceName,
                                               property);
    }

    template <class T>
    static boost::system::error_code setProperty(const std::string& path,
                                                 const std::string& property,
                                                 const T& newValue)
    {
        return DbusEnvironment::setProperty<T>(path, Trigger::triggerIfaceName,
                                               property, newValue);
    }

    template <class T>
    struct ChangePropertyParams
    {
        Matcher<T> valueBefore = _;
        T newValue;
        Matcher<boost::system::error_code> ec =
            Eq(boost::system::errc::success);
        Matcher<T> valueAfter = Eq(newValue);
    };

    template <class T>
    static void changeProperty(const std::string& path,
                               const std::string& property,
                               ChangePropertyParams<T> p)
    {
        ASSERT_THAT(getProperty<T>(path, property), p.valueBefore);
        ASSERT_THAT(setProperty<T>(path, property, p.newValue), p.ec);
        EXPECT_THAT(getProperty<T>(path, property), p.valueAfter);
    }

    boost::system::error_code deleteTrigger(const std::string& path)
    {
        std::promise<boost::system::error_code> methodPromise;
        DbusEnvironment::getBus()->async_method_call(
            [&methodPromise](boost::system::error_code ec) {
            methodPromise.set_value(ec);
            },
            DbusEnvironment::serviceName(), path, Trigger::deleteIfaceName,
            "Delete");
        return DbusEnvironment::waitForFuture(methodPromise.get_future());
    }
};

TEST_F(TestTrigger, checkIfPropertiesAreSet)
{
    EXPECT_THAT(getProperty<std::string>(sut->getPath(), "Name"),
                Eq(triggerParams.name()));
    EXPECT_THAT(getProperty<bool>(sut->getPath(), "Persistent"), Eq(true));
    EXPECT_THAT(
        getProperty<std::vector<std::string>>(sut->getPath(), "TriggerActions"),
        Eq(utils::transform(triggerParams.triggerActions(),
                            [](const auto& action) {
        return actionToString(action);
        })));
    EXPECT_THAT((getProperty<SensorsInfo>(sut->getPath(), "Sensors")),
                Eq(utils::fromLabeledSensorsInfo(triggerParams.sensors())));
    EXPECT_THAT(
        getProperty<std::vector<object_path>>(sut->getPath(), "Reports"),
        Eq(triggerParams.reports()));
    EXPECT_THAT(
        getProperty<bool>(sut->getPath(), "Discrete"),
        Eq(isTriggerThresholdDiscrete(triggerParams.thresholdParams())));
    EXPECT_THAT(
        getProperty<TriggerThresholdParams>(sut->getPath(), "Thresholds"),
        Eq(std::visit(utils::FromLabeledThresholdParamConversion(),
                      triggerParams.thresholdParams())));
}

TEST_F(TestTrigger, checkBasicGetters)
{
    EXPECT_THAT(sut->getId(), Eq(triggerParams.id()));
    EXPECT_THAT(sut->getPath(),
                Eq(utils::constants::triggerDirPath.str + triggerParams.id()));
}

TEST_F(TestTrigger, setPropertyNameToCorrectValue)
{
    std::string name = "custom name 1234 %^#5";
    EXPECT_THAT(setProperty(sut->getPath(), "Name", name),
                Eq(boost::system::errc::success));
    EXPECT_THAT(getProperty<std::string>(sut->getPath(), "Name"), Eq(name));
}

TEST_F(TestTrigger, setPropertyReportNames)
{
    std::vector<object_path> newNames = {
        utils::constants::reportDirPath / "abc",
        utils::constants::reportDirPath / "one",
        utils::constants::reportDirPath / "prefix" / "two"};
    EXPECT_THAT(setProperty(sut->getPath(), "Reports", newNames),
                Eq(boost::system::errc::success));
    EXPECT_THAT(
        getProperty<std::vector<object_path>>(sut->getPath(), "Reports"),
        Eq(newNames));
}

TEST_F(TestTrigger, sendsUpdateWhenReportNamesChanges)
{
    std::vector<object_path> newPropertyVal = {
        utils::constants::reportDirPath / "abc",
        utils::constants::reportDirPath / "one",
        utils::constants::reportDirPath / "two"};

    EXPECT_CALL(triggerPresenceChanged,
                Call(FieldsAre(messages::Presence::Exist, triggerParams.id(),
                               UnorderedElementsAre("abc", "one", "two"))));

    EXPECT_THAT(setProperty(sut->getPath(), "Reports", newPropertyVal),
                Eq(boost::system::errc::success));
}

TEST_F(TestTrigger, sendsUpdateWhenReportNamesChangesToSameValue)
{
    const std::vector<object_path> newPropertyVal = triggerParams.reports();

    EXPECT_CALL(
        triggerPresenceChanged,
        Call(FieldsAre(messages::Presence::Exist, triggerParams.id(),
                       UnorderedElementsAreArray(triggerParams.reportIds()))));

    EXPECT_THAT(setProperty(sut->getPath(), "Reports", newPropertyVal),
                Eq(boost::system::errc::success));
}

TEST_F(TestTrigger,
       DISABLED_settingPropertyReportNamesThrowsExceptionWhenDuplicateReportIds)
{
    std::vector<object_path> newPropertyVal{
        utils::constants::reportDirPath / "report1",
        utils::constants::reportDirPath / "report2",
        utils::constants::reportDirPath / "report1"};

    EXPECT_CALL(triggerPresenceChanged, Call(_)).Times(0);

    EXPECT_THAT(setProperty(sut->getPath(), "Reports", newPropertyVal),
                Eq(boost::system::errc::invalid_argument));
}

TEST_F(
    TestTrigger,
    DISABLED_settingPropertyReportNamesThrowsExceptionWhenReportWithTooManyPrefixes)
{
    std::vector<object_path> newPropertyVal{
        object_path("/xyz/openbmc_project/Telemetry/Reports/P1/P2/MyReport")};

    EXPECT_CALL(triggerPresenceChanged, Call(_)).Times(0);

    EXPECT_THAT(setProperty(sut->getPath(), "Reports", newPropertyVal),
                Eq(boost::system::errc::invalid_argument));
}

TEST_F(
    TestTrigger,
    DISABLED_settingPropertyReportNamesThrowsExceptionWhenReportWithTooLongPrefix)
{
    std::vector<object_path> newPropertyVal{
        object_path("/xyz/openbmc_project/Telemetry/Reports/" +
                    utils::string_utils::getTooLongPrefix() + "/MyReport")};

    EXPECT_CALL(triggerPresenceChanged, Call(_)).Times(0);

    EXPECT_THAT(setProperty(sut->getPath(), "Reports", newPropertyVal),
                Eq(boost::system::errc::invalid_argument));
}

TEST_F(
    TestTrigger,
    DISABLED_settingPropertyReportNamesThrowsExceptionWhenReportWithTooLongId)
{
    std::vector<object_path> newPropertyVal{
        object_path("/xyz/openbmc_project/Telemetry/Reports/Prefix/" +
                    utils::string_utils::getTooLongId())};

    EXPECT_CALL(triggerPresenceChanged, Call(_)).Times(0);

    EXPECT_THAT(setProperty(sut->getPath(), "Reports", newPropertyVal),
                Eq(boost::system::errc::invalid_argument));
}

TEST_F(TestTrigger,
       DISABLED_settingPropertyReportNamesThrowsExceptionWhenReportWithBadPath)
{
    std::vector<object_path> newPropertyVal{
        object_path("/xyz/openbmc_project/Telemetry/NotReports/MyReport")};

    EXPECT_CALL(triggerPresenceChanged, Call(_)).Times(0);

    EXPECT_THAT(setProperty(sut->getPath(), "Reports", newPropertyVal),
                Eq(boost::system::errc::invalid_argument));
}

TEST_F(TestTrigger, setPropertySensors)
{
    EXPECT_CALL(*triggerFactoryMockPtr, updateSensors(_, _));
    for (const auto& threshold : thresholdMocks)
    {
        auto thresholdMockPtr =
            std::dynamic_pointer_cast<NiceMock<ThresholdMock>>(threshold);
        EXPECT_CALL(*thresholdMockPtr, updateSensors(_));
    }
    SensorsInfo newSensors(
        {std::make_pair(object_path("/abc/def"), "metadata")});
    EXPECT_THAT(setProperty(sut->getPath(), "Sensors", newSensors),
                Eq(boost::system::errc::success));
}

TEST_F(TestTrigger, setPropertyThresholds)
{
    EXPECT_CALL(*triggerFactoryMockPtr, updateThresholds(_, _, _, _, _, _));
    TriggerThresholdParams newThresholds =
        std::vector<discrete::ThresholdParam>({std::make_tuple(
            "discrete threshold", utils::enumToString(discrete::Severity::ok),
            10, "12.3")});
    EXPECT_THAT(setProperty(sut->getPath(), "Thresholds", newThresholds),
                Eq(boost::system::errc::success));
}

TEST_F(TestTrigger, setThresholdParamsWithTooLongDiscreteName)
{
    const TriggerThresholdParams currentValue =
        std::visit(utils::FromLabeledThresholdParamConversion(),
                   triggerParams.thresholdParams());

    TriggerThresholdParams newThresholds =
        std::vector<discrete::ThresholdParam>({std::make_tuple(
            utils::string_utils::getTooLongName(),
            utils::enumToString(discrete::Severity::ok), 10, "12.3")});

    changeProperty<TriggerThresholdParams>(
        sut->getPath(), "Thresholds",
        {.valueBefore = Eq(currentValue),
         .newValue = newThresholds,
         .ec = Eq(boost::system::errc::invalid_argument),
         .valueAfter = Eq(currentValue)});
}

TEST_F(TestTrigger, setNameTooLong)
{
    std::string currentValue = TriggerParams().name();

    changeProperty<std::string>(
        sut->getPath(), "Name",
        {.valueBefore = Eq(currentValue),
         .newValue = utils::string_utils::getTooLongName(),
         .ec = Eq(boost::system::errc::invalid_argument),
         .valueAfter = Eq(currentValue)});
}

TEST_F(TestTrigger, checkIfNumericCoversionsAreGood)
{
    const auto& labeledParamsBase =
        std::get<std::vector<numeric::LabeledThresholdParam>>(
            triggerParams.thresholdParams());
    const auto paramsToCheck =
        std::visit(utils::FromLabeledThresholdParamConversion(),
                   triggerParams.thresholdParams());
    const auto labeledParamsToCheck =
        std::get<std::vector<numeric::LabeledThresholdParam>>(std::visit(
            utils::ToLabeledThresholdParamConversion(), paramsToCheck));

    for (const auto& [tocheck, base] :
         boost::combine(labeledParamsToCheck, labeledParamsBase))
    {
        EXPECT_THAT(tocheck.at_label<utils::tstring::Type>(),
                    Eq(base.at_label<utils::tstring::Type>()));
        EXPECT_THAT(tocheck.at_label<utils::tstring::Direction>(),
                    Eq(base.at_label<utils::tstring::Direction>()));
        EXPECT_THAT(tocheck.at_label<utils::tstring::DwellTime>(),
                    Eq(base.at_label<utils::tstring::DwellTime>()));
        EXPECT_THAT(tocheck.at_label<utils::tstring::ThresholdValue>(),
                    Eq(base.at_label<utils::tstring::ThresholdValue>()));
    }
}

TEST_F(TestTrigger, checkIfDiscreteCoversionsAreGood)
{
    const auto& labeledParamsBase =
        std::get<std::vector<discrete::LabeledThresholdParam>>(
            triggerDiscreteParams.thresholdParams());
    const auto paramsToCheck =
        std::visit(utils::FromLabeledThresholdParamConversion(),
                   triggerDiscreteParams.thresholdParams());
    const auto labeledParamsToCheck =
        std::get<std::vector<discrete::LabeledThresholdParam>>(std::visit(
            utils::ToLabeledThresholdParamConversion(), paramsToCheck));

    for (const auto& [tocheck, base] :
         boost::combine(labeledParamsToCheck, labeledParamsBase))
    {
        EXPECT_THAT(tocheck.at_label<utils::tstring::UserId>(),
                    Eq(base.at_label<utils::tstring::UserId>()));
        EXPECT_THAT(tocheck.at_label<utils::tstring::Severity>(),
                    Eq(base.at_label<utils::tstring::Severity>()));
        EXPECT_THAT(tocheck.at_label<utils::tstring::DwellTime>(),
                    Eq(base.at_label<utils::tstring::DwellTime>()));
        EXPECT_THAT(tocheck.at_label<utils::tstring::ThresholdValue>(),
                    Eq(base.at_label<utils::tstring::ThresholdValue>()));
    }
}

TEST_F(TestTrigger, deleteTrigger)
{
    EXPECT_CALL(storageMock, remove(to_file_path(sut->getId())));
    EXPECT_CALL(*triggerManagerMockPtr, removeTrigger(sut.get()));

    auto ec = deleteTrigger(sut->getPath());
    EXPECT_THAT(ec, Eq(boost::system::errc::success));
}

TEST_F(TestTrigger, sendUpdateWhenTriggerIsDeleted)
{
    EXPECT_CALL(triggerPresenceChanged,
                Call(FieldsAre(messages::Presence::Removed, triggerParams.id(),
                               UnorderedElementsAre())));

    auto ec = deleteTrigger(sut->getPath());
    EXPECT_THAT(ec, Eq(boost::system::errc::success));
}

TEST_F(TestTrigger, deletingNonExistingTriggerReturnInvalidRequestDescriptor)
{
    auto ec =
        deleteTrigger(utils::constants::triggerDirPath.str + "NonExisting"s);
    EXPECT_THAT(ec.value(), Eq(EBADR));
}

TEST_F(TestTrigger, settingPersistencyToFalseRemovesTriggerFromStorage)
{
    EXPECT_CALL(storageMock, remove(to_file_path(sut->getId())));

    bool persistent = false;
    EXPECT_THAT(setProperty(sut->getPath(), "Persistent", persistent),
                Eq(boost::system::errc::success));
    EXPECT_THAT(getProperty<bool>(sut->getPath(), "Persistent"),
                Eq(persistent));
}

class TestTriggerInitialization : public TestTrigger
{
  public:
    void SetUp() override {}

    nlohmann::json storedConfiguration;
};

TEST_F(TestTriggerInitialization,
       exceptionDuringTriggerStoreDisablesPersistency)
{
    EXPECT_CALL(storageMock, store(_, _))
        .WillOnce(Throw(std::runtime_error("Generic error!")));

    sut = makeTrigger(triggerParams);

    EXPECT_THAT(getProperty<bool>(sut->getPath(), "Persistent"), Eq(false));
}

TEST_F(TestTriggerInitialization, creatingTriggerThrowsExceptionWhenIdIsInvalid)
{
    EXPECT_CALL(storageMock, store(_, _)).Times(0);

    EXPECT_THROW(makeTrigger(triggerParams.id("inv?lidId")),
                 sdbusplus::exception::SdBusError);
}

TEST_F(TestTriggerInitialization, creatingTriggerUpdatesTriggersIdsInReports)
{
    EXPECT_CALL(
        triggerPresenceChanged,
        Call(FieldsAre(messages::Presence::Exist, triggerParams.id(),
                       UnorderedElementsAreArray(triggerParams.reportIds()))));

    sut = makeTrigger(triggerParams);
}

class TestTriggerStore : public TestTrigger
{
  public:
    nlohmann::json storedConfiguration;
    nlohmann::json storedDiscreteConfiguration;
    std::unique_ptr<Trigger> sutDiscrete;

    void SetUp() override
    {
        ON_CALL(storageMock, store(_, _))
            .WillByDefault(SaveArg<1>(&storedConfiguration));
        sut = makeTrigger(triggerParams);

        ON_CALL(storageMock, store(_, _))
            .WillByDefault(SaveArg<1>(&storedDiscreteConfiguration));
        sutDiscrete = makeTrigger(triggerDiscreteParams);
    }
};

TEST_F(TestTriggerStore, settingPersistencyToTrueStoresTriggerVersion)
{
    ASSERT_THAT(storedConfiguration.at("Version"), Eq(expectedTriggerVersion));
}

TEST_F(TestTriggerStore, settingPersistencyToTrueStoresTriggerId)
{
    ASSERT_THAT(storedConfiguration.at("Id"), Eq(triggerParams.id()));
}

TEST_F(TestTriggerStore, settingPersistencyToTrueStoresTriggerName)
{
    ASSERT_THAT(storedConfiguration.at("Name"), Eq(triggerParams.name()));
}

TEST_F(TestTriggerStore, settingPersistencyToTrueStoresTriggerTriggerActions)
{
    ASSERT_THAT(storedConfiguration.at("TriggerActions"),
                Eq(utils::transform(triggerParams.triggerActions(),
                                    [](const auto& action) {
        return actionToString(action);
                })));
}

TEST_F(TestTriggerStore, settingPersistencyToTrueStoresTriggerReportIds)
{
    ASSERT_THAT(storedConfiguration.at("ReportIds"),
                Eq(triggerParams.reportIds()));
}

TEST_F(TestTriggerStore, settingPersistencyToTrueStoresTriggerSensors)
{
    nlohmann::json expectedItem;
    expectedItem["service"] = "service1";
    expectedItem["path"] = "/xyz/openbmc_project/sensors/temperature/BMC_Temp";
    expectedItem["metadata"] = "metadata1";

    ASSERT_THAT(storedConfiguration.at("Sensors"), ElementsAre(expectedItem));
}

TEST_F(TestTriggerStore, settingPersistencyToTrueStoresTriggerThresholdParams)
{
    nlohmann::json expectedItem0;
    expectedItem0["type"] = 0;
    expectedItem0["dwellTime"] = 10;
    expectedItem0["direction"] = 1;
    expectedItem0["thresholdValue"] = 0.5;

    nlohmann::json expectedItem1;
    expectedItem1["type"] = 3;
    expectedItem1["dwellTime"] = 10;
    expectedItem1["direction"] = 2;
    expectedItem1["thresholdValue"] = 90.2;

    ASSERT_THAT(storedConfiguration.at("ThresholdParamsDiscriminator"), Eq(0));
    ASSERT_THAT(storedConfiguration.at("ThresholdParams"),
                ElementsAre(expectedItem0, expectedItem1));
}

TEST_F(TestTriggerStore,
       settingPersistencyToTrueStoresDiscreteTriggerThresholdParams)
{
    nlohmann::json expectedItem0;
    expectedItem0["userId"] = "userId";
    expectedItem0["severity"] = discrete::Severity::warning;
    expectedItem0["dwellTime"] = 10;
    expectedItem0["thresholdValue"] = "15.2";

    nlohmann::json expectedItem1;
    expectedItem1["userId"] = "userId_2";
    expectedItem1["severity"] = discrete::Severity::critical;
    expectedItem1["dwellTime"] = 5;
    expectedItem1["thresholdValue"] = "32.7";

    ASSERT_THAT(storedDiscreteConfiguration.at("ThresholdParamsDiscriminator"),
                Eq(1));
    ASSERT_THAT(storedDiscreteConfiguration.at("ThresholdParams"),
                ElementsAre(expectedItem0, expectedItem1));
}
