/*
 *    Copyright (c) 2024 Project CHIP Authors
 *
 *    Licensed under the Apache License, Version 2.0 (the "License");
 *    you may not use this file except in compliance with the License.
 *    You may obtain a copy of the License at
 *
 *        http://www.apache.org/licenses/LICENSE-2.0
 *
 *    Unless required by applicable law or agreed to in writing, software
 *    distributed under the License is distributed on an "AS IS" BASIS,
 *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *    See the License for the specific language governing permissions and
 *    limitations under the License.
 */
#include <gtest/gtest.h>
#include <lib/support/UnitTestRegistration.h>
#include <tracing/backend.h>
#include <tracing/metric_event.h>

#include <algorithm>
#include <string>
#include <vector>

using namespace chip;
using namespace chip::Tracing;

namespace chip {
namespace Tracing {

static bool operator==(const MetricEvent & lhs, const MetricEvent & rhs)
{
    if (&lhs == &rhs)
    {
        return true;
    }

    if (lhs.type() == rhs.type() && std::string(lhs.key()) == std::string(rhs.key()) && lhs.ValueType() == rhs.ValueType())
    {
        switch (lhs.ValueType())
        {
        case MetricEvent::Value::Type::kInt32:
            return lhs.ValueInt32() == rhs.ValueInt32();

        case MetricEvent::Value::Type::kUInt32:
            return lhs.ValueUInt32() == rhs.ValueUInt32();

        case MetricEvent::Value::Type::kChipErrorCode:
            return lhs.ValueErrorCode() == rhs.ValueErrorCode();

        case MetricEvent::Value::Type::kUndefined:
            return true;
        }
    }
    return false;
}
} // namespace Tracing
} // namespace chip

namespace {

// This keeps a log of all received trace items
class MetricEventBackend : public Backend
{
public:
    MetricEventBackend() {}
    const std::vector<MetricEvent> & GetMetricEvents() const { return mMetricEvents; }

    // Implementation
    virtual void LogMetricEvent(const MetricEvent & event) { mMetricEvents.push_back(event); }

private:
    std::vector<MetricEvent> mMetricEvents;
};

TEST(TestMetricEvents, TestBasicMetricEvent)
{

    {
        MetricEvent event(MetricEvent::Type::kInstantEvent, "instant_event");
        EXPECT_EQ(event.type(), MetricEvent::Type::kInstantEvent);
        EXPECT_EQ(std::string(event.key()), std::string("instant_event"));
        EXPECT_EQ(event.ValueType(), MetricEvent::Value::Type::kUndefined);
    }

    {
        MetricEvent event(MetricEvent::Type::kBeginEvent, "begin_event");
        EXPECT_EQ(event.type(), MetricEvent::Type::kBeginEvent);
        EXPECT_EQ(std::string(event.key()), std::string("begin_event"));
        EXPECT_EQ(event.ValueType(), MetricEvent::Value::Type::kUndefined);
    }

    {
        MetricEvent event(MetricEvent::Type::kEndEvent, "end_event");
        EXPECT_EQ(event.type(), MetricEvent::Type::kEndEvent);
        EXPECT_EQ(std::string(event.key()), std::string("end_event"));
        EXPECT_EQ(event.ValueType(), MetricEvent::Value::Type::kUndefined);
    }

    {
        MetricEvent event(MetricEvent::Type::kEndEvent, "end_event_with_int32_value", int32_t(42));
        EXPECT_EQ(event.type(), MetricEvent::Type::kEndEvent);
        EXPECT_EQ(std::string(event.key()), std::string("end_event_with_int32_value"));
        EXPECT_EQ(event.ValueType(), MetricEvent::Value::Type::kInt32);
        EXPECT_EQ(event.ValueInt32(), 42);
    }

    {
        MetricEvent event(MetricEvent::Type::kEndEvent, "end_event_with_uint32_value", uint32_t(42));
        EXPECT_EQ(event.type(), MetricEvent::Type::kEndEvent);
        EXPECT_EQ(std::string(event.key()), std::string("end_event_with_uint32_value"));
        EXPECT_EQ(event.ValueType(), MetricEvent::Value::Type::kUInt32);
        EXPECT_EQ(event.ValueUInt32(), 42u);
    }

    {
        MetricEvent event(MetricEvent::Type::kEndEvent, "end_event_with_error_value", CHIP_ERROR_BUSY);
        EXPECT_EQ(event.type(), MetricEvent::Type::kEndEvent);
        EXPECT_EQ(std::string(event.key()), std::string("end_event_with_error_value"));
        EXPECT_EQ(event.ValueType(), MetricEvent::Value::Type::kChipErrorCode);
        EXPECT_EQ(chip::ChipError(event.ValueErrorCode()), CHIP_ERROR_BUSY);
    }
}

TEST(TestMetricEvents, TestInstantMetricEvent)
{
    MetricEventBackend backend;

    {
        ScopedRegistration scope(backend);

        MATTER_LOG_METRIC("event1");
        MATTER_LOG_METRIC("event2");
        MATTER_LOG_METRIC("event3");
    }

    std::vector<MetricEvent> expected = {
        MetricEvent(MetricEvent::Type::kInstantEvent, "event1"),
        MetricEvent(MetricEvent::Type::kInstantEvent, "event2"),
        MetricEvent(MetricEvent::Type::kInstantEvent, "event3"),
    };

    EXPECT_EQ(backend.GetMetricEvents().size(), expected.size());
    EXPECT_TRUE(std::equal(backend.GetMetricEvents().begin(), backend.GetMetricEvents().end(), expected.begin(), expected.end()));
}

TEST(TestMetricEvents, TestBeginEndMetricEvent)
{
    MetricEventBackend backend1;
    MetricEventBackend backend2;

    {
        ScopedRegistration scope1(backend1);
        {

            MATTER_LOG_METRIC_BEGIN("event1");
            MATTER_LOG_METRIC_BEGIN("event2");
            MATTER_LOG_METRIC_END("event2", 53);
            MATTER_LOG_METRIC_END("event1");
        }

        std::vector<MetricEvent> expected1 = {
            MetricEvent(MetricEvent::Type::kBeginEvent, "event1"),
            MetricEvent(MetricEvent::Type::kBeginEvent, "event2"),
            MetricEvent(MetricEvent::Type::kEndEvent, "event2", 53),
            MetricEvent(MetricEvent::Type::kEndEvent, "event1"),
        };

        EXPECT_EQ(backend1.GetMetricEvents().size(), expected1.size());
        EXPECT_TRUE(
            std::equal(backend1.GetMetricEvents().begin(), backend1.GetMetricEvents().end(), expected1.begin(), expected1.end()));

        {
            ScopedRegistration scope2(backend2);

            MATTER_LOG_METRIC_BEGIN("event1");
            MATTER_LOG_METRIC_BEGIN("event2");
            MATTER_LOG_METRIC_BEGIN("event3");
            MATTER_LOG_METRIC_BEGIN("event4");
            MATTER_LOG_METRIC_END("event3", CHIP_ERROR_UNKNOWN_KEY_TYPE);
            MATTER_LOG_METRIC_END("event1", 91u);
            MATTER_LOG_METRIC_END("event2", 53);
            MATTER_LOG_METRIC_END("event4");
        }

        std::vector<MetricEvent> expected2 = {
            MetricEvent(MetricEvent::Type::kBeginEvent, "event1"),
            MetricEvent(MetricEvent::Type::kBeginEvent, "event2"),
            MetricEvent(MetricEvent::Type::kBeginEvent, "event3"),
            MetricEvent(MetricEvent::Type::kBeginEvent, "event4"),
            MetricEvent(MetricEvent::Type::kEndEvent, "event3", CHIP_ERROR_UNKNOWN_KEY_TYPE),
            MetricEvent(MetricEvent::Type::kEndEvent, "event1", 91u),
            MetricEvent(MetricEvent::Type::kEndEvent, "event2", 53),
            MetricEvent(MetricEvent::Type::kEndEvent, "event4"),
        };

        EXPECT_EQ(backend2.GetMetricEvents().size(), expected2.size());
        EXPECT_TRUE(
            std::equal(backend2.GetMetricEvents().begin(), backend2.GetMetricEvents().end(), expected2.begin(), expected2.end()));
    }
}

TEST(TestMetricEvents, TestScopedMetricEvent)
{
    MetricEventBackend backend1;
    MetricEventBackend backend2;
    MetricEventBackend backend3;
    chip::ChipError err1 = CHIP_NO_ERROR;
    chip::ChipError err2 = CHIP_NO_ERROR;
    chip::ChipError err3 = CHIP_NO_ERROR;
    chip::ChipError err4 = CHIP_NO_ERROR;

    {
        ScopedRegistration scope1(backend1);
        {
            MATTER_LOG_METRIC_SCOPE("event1", err1);
            err1 = CHIP_ERROR_BUSY;
            {
                ScopedRegistration scope2(backend2);
                MATTER_LOG_METRIC_SCOPE("event2", err2);
                err2 = CHIP_ERROR_BAD_REQUEST;

                {
                    ScopedRegistration scope3(backend3);
                    MATTER_LOG_METRIC_SCOPE("event3", err3);
                    err3 = CHIP_ERROR_EVENT_ID_FOUND;
                }
                {
                    MATTER_LOG_METRIC_SCOPE("event4", err4);
                    err4 = CHIP_ERROR_BUFFER_TOO_SMALL;
                }
            }
        }

        std::vector<MetricEvent> expected1 = {
            MetricEvent(MetricEvent::Type::kBeginEvent, "event1"),
            MetricEvent(MetricEvent::Type::kBeginEvent, "event2"),
            MetricEvent(MetricEvent::Type::kBeginEvent, "event3"),
            MetricEvent(MetricEvent::Type::kEndEvent, "event3", CHIP_ERROR_EVENT_ID_FOUND),
            MetricEvent(MetricEvent::Type::kBeginEvent, "event4"),
            MetricEvent(MetricEvent::Type::kEndEvent, "event4", CHIP_ERROR_BUFFER_TOO_SMALL),
            MetricEvent(MetricEvent::Type::kEndEvent, "event2", CHIP_ERROR_BAD_REQUEST),
            MetricEvent(MetricEvent::Type::kEndEvent, "event1", CHIP_ERROR_BUSY),
        };

        EXPECT_EQ(backend1.GetMetricEvents().size(), expected1.size());
        EXPECT_TRUE(
            std::equal(backend1.GetMetricEvents().begin(), backend1.GetMetricEvents().end(), expected1.begin(), expected1.end()));

        std::vector<MetricEvent> expected2 = {
            MetricEvent(MetricEvent::Type::kBeginEvent, "event2"),
            MetricEvent(MetricEvent::Type::kBeginEvent, "event3"),
            MetricEvent(MetricEvent::Type::kEndEvent, "event3", CHIP_ERROR_EVENT_ID_FOUND),
            MetricEvent(MetricEvent::Type::kBeginEvent, "event4"),
            MetricEvent(MetricEvent::Type::kEndEvent, "event4", CHIP_ERROR_BUFFER_TOO_SMALL),
            MetricEvent(MetricEvent::Type::kEndEvent, "event2", CHIP_ERROR_BAD_REQUEST),
        };

        EXPECT_EQ(backend2.GetMetricEvents().size(), expected2.size());
        EXPECT_TRUE(
            std::equal(backend2.GetMetricEvents().begin(), backend2.GetMetricEvents().end(), expected2.begin(), expected2.end()));

        std::vector<MetricEvent> expected3 = {
            MetricEvent(MetricEvent::Type::kBeginEvent, "event3"),
            MetricEvent(MetricEvent::Type::kEndEvent, "event3", CHIP_ERROR_EVENT_ID_FOUND),
        };

        EXPECT_EQ(backend3.GetMetricEvents().size(), expected3.size());
        EXPECT_TRUE(
            std::equal(backend3.GetMetricEvents().begin(), backend3.GetMetricEvents().end(), expected3.begin(), expected3.end()));
    }
}

static int DoubleOf(int input)
{
    return input * 2;
}

TEST(TestMetricEvents, TestVerifyOrExitWithMetric)
{
    MetricEventBackend backend;
    ScopedRegistration scope(backend);
    chip::ChipError err = CHIP_NO_ERROR;

    VerifyOrExitWithMetric("event0", DoubleOf(2) == 4, err = CHIP_ERROR_BAD_REQUEST);
    VerifyOrExitWithMetric("event1", DoubleOf(3) == 9, err = CHIP_ERROR_INCORRECT_STATE);

exit:
    std::vector<MetricEvent> expected = {
        MetricEvent(MetricEvent::Type::kInstantEvent, "event1", CHIP_ERROR_INCORRECT_STATE),
    };

    EXPECT_EQ(err, CHIP_ERROR_INCORRECT_STATE);
    EXPECT_EQ(backend.GetMetricEvents().size(), expected.size());
    EXPECT_TRUE(std::equal(backend.GetMetricEvents().begin(), backend.GetMetricEvents().end(), expected.begin(), expected.end()));
}

TEST(TestMetricEvents, TestSuccessOrExitWithMetric)
{
    MetricEventBackend backend;
    ScopedRegistration scope(backend);
    chip::ChipError err = CHIP_NO_ERROR;

    SuccessOrExitWithMetric("event1", err = CHIP_NO_ERROR);
    SuccessOrExitWithMetric("event2", err = CHIP_ERROR_BUSY);
    SuccessOrExitWithMetric("event3", err = CHIP_NO_ERROR);

exit:
    std::vector<MetricEvent> expected = {
        MetricEvent(MetricEvent::Type::kInstantEvent, "event2", CHIP_ERROR_BUSY),
    };

    EXPECT_EQ(err, CHIP_ERROR_BUSY);
    EXPECT_EQ(backend.GetMetricEvents().size(), expected.size());
    EXPECT_TRUE(std::equal(backend.GetMetricEvents().begin(), backend.GetMetricEvents().end(), expected.begin(), expected.end()));
}

static CHIP_ERROR InvokeReturnErrorOnFailureWithMetric(MetricKey key, const CHIP_ERROR & error)
{
    ReturnErrorOnFailureWithMetric(key, error);
    return CHIP_NO_ERROR;
}

TEST(TestMetricEvents, TestReturnErrorOnFailureWithMetric)
{
    MetricEventBackend backend;
    ScopedRegistration scope(backend);

    CHIP_ERROR err = InvokeReturnErrorOnFailureWithMetric("event0", CHIP_NO_ERROR);
    EXPECT_EQ(err, CHIP_NO_ERROR);

    err = InvokeReturnErrorOnFailureWithMetric("event1", CHIP_ERROR_INCORRECT_STATE);
    EXPECT_EQ(err, CHIP_ERROR_INCORRECT_STATE);

    err = InvokeReturnErrorOnFailureWithMetric("event2", CHIP_ERROR_BAD_REQUEST);
    EXPECT_EQ(err, CHIP_ERROR_BAD_REQUEST);

    std::vector<MetricEvent> expected = {
        MetricEvent(MetricEvent::Type::kInstantEvent, "event1", CHIP_ERROR_INCORRECT_STATE),
        MetricEvent(MetricEvent::Type::kInstantEvent, "event2", CHIP_ERROR_BAD_REQUEST),
    };

    EXPECT_EQ(backend.GetMetricEvents().size(), expected.size());
    EXPECT_TRUE(std::equal(backend.GetMetricEvents().begin(), backend.GetMetricEvents().end(), expected.begin(), expected.end()));
}

static CHIP_ERROR InvokeReturnLogErrorOnFailureWithMetric(MetricKey key, const CHIP_ERROR & error)
{
    ReturnLogErrorOnFailureWithMetric(key, error);
    return CHIP_NO_ERROR;
}

TEST(TestMetricEvents, TestReturnLogErrorOnFailureWithMetric)
{
    MetricEventBackend backend;
    ScopedRegistration scope(backend);

    CHIP_ERROR err = InvokeReturnLogErrorOnFailureWithMetric("event0", CHIP_NO_ERROR);
    EXPECT_EQ(err, CHIP_NO_ERROR);

    err = InvokeReturnLogErrorOnFailureWithMetric("event1", CHIP_ERROR_INCORRECT_STATE);
    EXPECT_EQ(err, CHIP_ERROR_INCORRECT_STATE);

    err = InvokeReturnLogErrorOnFailureWithMetric("event2", CHIP_ERROR_BAD_REQUEST);
    EXPECT_EQ(err, CHIP_ERROR_BAD_REQUEST);

    std::vector<MetricEvent> expected = {
        MetricEvent(MetricEvent::Type::kInstantEvent, "event1", CHIP_ERROR_INCORRECT_STATE),
        MetricEvent(MetricEvent::Type::kInstantEvent, "event2", CHIP_ERROR_BAD_REQUEST),
    };

    EXPECT_EQ(backend.GetMetricEvents().size(), expected.size());
    EXPECT_TRUE(std::equal(backend.GetMetricEvents().begin(), backend.GetMetricEvents().end(), expected.begin(), expected.end()));
}

static void InvokeReturnOnFailureWithMetric(MetricKey key, const CHIP_ERROR & error)
{
    ReturnOnFailureWithMetric(key, error);
    return;
}

TEST(TestMetricEvents, TestReturnOnFailureWithMetric)
{
    MetricEventBackend backend;
    ScopedRegistration scope(backend);

    InvokeReturnOnFailureWithMetric("event0", CHIP_NO_ERROR);

    InvokeReturnOnFailureWithMetric("event1", CHIP_ERROR_INCORRECT_STATE);

    InvokeReturnOnFailureWithMetric("event2", CHIP_ERROR_BAD_REQUEST);

    std::vector<MetricEvent> expected = {
        MetricEvent(MetricEvent::Type::kInstantEvent, "event1", CHIP_ERROR_INCORRECT_STATE),
        MetricEvent(MetricEvent::Type::kInstantEvent, "event2", CHIP_ERROR_BAD_REQUEST),
    };

    EXPECT_EQ(backend.GetMetricEvents().size(), expected.size());
    EXPECT_TRUE(std::equal(backend.GetMetricEvents().begin(), backend.GetMetricEvents().end(), expected.begin(), expected.end()));
}

static void InvokeVerifyOrReturnWithMetric(MetricKey key, bool result)
{
    VerifyOrReturnWithMetric(key, result);
    return;
}

TEST(TestMetricEvents, TestInvokeVerifyOrReturnWithMetric)
{
    MetricEventBackend backend;
    ScopedRegistration scope(backend);

    InvokeVerifyOrReturnWithMetric("event0", DoubleOf(2) == 4);
    InvokeVerifyOrReturnWithMetric("event1", DoubleOf(3) == 9);
    InvokeVerifyOrReturnWithMetric("event2", DoubleOf(4) == 8);
    InvokeVerifyOrReturnWithMetric("event3", DoubleOf(5) == 11);

    std::vector<MetricEvent> expected = {
        MetricEvent(MetricEvent::Type::kInstantEvent, "event1", false),
        MetricEvent(MetricEvent::Type::kInstantEvent, "event3", false),
    };

    EXPECT_EQ(backend.GetMetricEvents().size(), expected.size());
    EXPECT_TRUE(std::equal(backend.GetMetricEvents().begin(), backend.GetMetricEvents().end(), expected.begin(), expected.end()));
}

static CHIP_ERROR InvokeVerifyOrReturnErrorWithMetric(MetricKey key, bool expr, const CHIP_ERROR & error)
{
    VerifyOrReturnErrorWithMetric(key, expr, error);
    return CHIP_NO_ERROR;
}

TEST(TestMetricEvents, TestVerifyOrReturnErrorWithMetric)
{
    MetricEventBackend backend;
    ScopedRegistration scope(backend);

    CHIP_ERROR err = InvokeVerifyOrReturnErrorWithMetric("event0", DoubleOf(2) == 4, CHIP_ERROR_BAD_REQUEST);
    EXPECT_EQ(err, CHIP_NO_ERROR);

    err = InvokeVerifyOrReturnErrorWithMetric("event1", DoubleOf(3) == 9, CHIP_ERROR_ACCESS_DENIED);
    EXPECT_EQ(err, CHIP_ERROR_ACCESS_DENIED);

    err = InvokeVerifyOrReturnErrorWithMetric("event2", DoubleOf(4) == 8, CHIP_ERROR_BUSY);
    EXPECT_EQ(err, CHIP_NO_ERROR);

    err = InvokeVerifyOrReturnErrorWithMetric("event3", DoubleOf(5) == 11, CHIP_ERROR_CANCELLED);
    EXPECT_EQ(err, CHIP_ERROR_CANCELLED);

    std::vector<MetricEvent> expected = {
        MetricEvent(MetricEvent::Type::kInstantEvent, "event1", CHIP_ERROR_ACCESS_DENIED),
        MetricEvent(MetricEvent::Type::kInstantEvent, "event3", CHIP_ERROR_CANCELLED),
    };

    EXPECT_EQ(backend.GetMetricEvents().size(), expected.size());
    EXPECT_TRUE(std::equal(backend.GetMetricEvents().begin(), backend.GetMetricEvents().end(), expected.begin(), expected.end()));
}

template <typename return_code_type>
static return_code_type InvokeVerifyOrReturnValueWithMetric(MetricKey key, bool expr, return_code_type retval)
{
    VerifyOrReturnValueWithMetric(key, expr, retval);
    return return_code_type();
}

TEST(TestMetricEvents, TestVerifyOrReturnValueWithMetric)
{
    MetricEventBackend backend;
    ScopedRegistration scope(backend);

    auto retval = InvokeVerifyOrReturnValueWithMetric("event0", DoubleOf(2) == 4, 0);
    EXPECT_EQ(retval, 0);

    auto err = InvokeVerifyOrReturnValueWithMetric("event1", DoubleOf(3) == 9, CHIP_ERROR_ACCESS_DENIED);
    EXPECT_EQ(err, CHIP_ERROR_ACCESS_DENIED);

    err = InvokeVerifyOrReturnValueWithMetric("event2", DoubleOf(4) == 8, CHIP_ERROR_BAD_REQUEST);
    EXPECT_EQ(err, CHIP_NO_ERROR);

    retval = InvokeVerifyOrReturnValueWithMetric("event3", DoubleOf(5) == 11, 16);
    EXPECT_EQ(retval, 16);

    std::vector<MetricEvent> expected = {
        MetricEvent(MetricEvent::Type::kInstantEvent, "event1", CHIP_ERROR_ACCESS_DENIED),
        MetricEvent(MetricEvent::Type::kInstantEvent, "event3", 16),
    };

    EXPECT_EQ(backend.GetMetricEvents().size(), expected.size());
    EXPECT_TRUE(std::equal(backend.GetMetricEvents().begin(), backend.GetMetricEvents().end(), expected.begin(), expected.end()));
}

static CHIP_ERROR InvokeVerifyOrReturnLogErrorWithMetric(MetricKey key, bool expr, const CHIP_ERROR & error)
{
    VerifyOrReturnLogErrorWithMetric(key, expr, error);
    return CHIP_NO_ERROR;
}

TEST(TestMetricEvents, TestVerifyOrReturnLogErrorWithMetric)
{
    MetricEventBackend backend;
    ScopedRegistration scope(backend);

    auto err = InvokeVerifyOrReturnLogErrorWithMetric("event0", DoubleOf(2) == 4, CHIP_NO_ERROR);
    EXPECT_EQ(err, CHIP_NO_ERROR);

    err = InvokeVerifyOrReturnLogErrorWithMetric("event1", DoubleOf(3) == 9, CHIP_ERROR_CANCELLED);
    EXPECT_EQ(err, CHIP_ERROR_CANCELLED);

    err = InvokeVerifyOrReturnLogErrorWithMetric("event2", DoubleOf(4) == 8, CHIP_NO_ERROR);
    EXPECT_EQ(err, CHIP_NO_ERROR);

    err = InvokeVerifyOrReturnLogErrorWithMetric("event3", DoubleOf(5) == 11, CHIP_ERROR_BAD_REQUEST);
    EXPECT_EQ(err, CHIP_ERROR_BAD_REQUEST);

    std::vector<MetricEvent> expected = {
        MetricEvent(MetricEvent::Type::kInstantEvent, "event1", CHIP_ERROR_CANCELLED),
        MetricEvent(MetricEvent::Type::kInstantEvent, "event3", CHIP_ERROR_BAD_REQUEST),
    };

    EXPECT_EQ(backend.GetMetricEvents().size(), expected.size());
    EXPECT_TRUE(std::equal(backend.GetMetricEvents().begin(), backend.GetMetricEvents().end(), expected.begin(), expected.end()));
}

template <typename return_code_type>
static return_code_type InvokeReturnErrorCodeWithMetricIf(MetricKey key, bool expr, const return_code_type & code)
{
    ReturnErrorCodeWithMetricIf(key, expr, code);
    return return_code_type();
}

TEST(TestMetricEvents, TestReturnErrorCodeWithMetricIf)
{
    MetricEventBackend backend;
    ScopedRegistration scope(backend);

    auto err = InvokeReturnErrorCodeWithMetricIf("event0", DoubleOf(2) == 4, CHIP_ERROR_DUPLICATE_KEY_ID);
    EXPECT_EQ(err, CHIP_ERROR_DUPLICATE_KEY_ID);

    auto retval = InvokeReturnErrorCodeWithMetricIf("event1", DoubleOf(3) == 9, 11);
    EXPECT_EQ(retval, 0);

    retval = InvokeReturnErrorCodeWithMetricIf("event2", DoubleOf(4) == 8, 22);
    EXPECT_EQ(retval, 22);

    err = InvokeReturnErrorCodeWithMetricIf("event3", DoubleOf(5) == 11, CHIP_ERROR_ACCESS_DENIED);
    EXPECT_EQ(err, CHIP_NO_ERROR);

    std::vector<MetricEvent> expected = {
        MetricEvent(MetricEvent::Type::kInstantEvent, "event0", CHIP_ERROR_DUPLICATE_KEY_ID),
        MetricEvent(MetricEvent::Type::kInstantEvent, "event2", 22),
    };

    EXPECT_EQ(backend.GetMetricEvents().size(), expected.size());
    EXPECT_TRUE(std::equal(backend.GetMetricEvents().begin(), backend.GetMetricEvents().end(), expected.begin(), expected.end()));
}

TEST(TestMetricEvents, TestExitNowWithMetric)
{
    MetricEventBackend backend;
    ScopedRegistration scope(backend);
    chip::ChipError err = CHIP_NO_ERROR;

    ExitNowWithMetric("event0", err = CHIP_ERROR_BUSY);

exit:
    std::vector<MetricEvent> expected = {
        MetricEvent(MetricEvent::Type::kInstantEvent, "event0"),
    };

    EXPECT_EQ(err, CHIP_ERROR_BUSY);
    EXPECT_EQ(backend.GetMetricEvents().size(), expected.size());
    EXPECT_TRUE(std::equal(backend.GetMetricEvents().begin(), backend.GetMetricEvents().end(), expected.begin(), expected.end()));
}

TEST(TestMetricEvents, TestLogErrorOnFailureWithMetric)
{
    MetricEventBackend backend;
    ScopedRegistration scope(backend);

    LogErrorOnFailureWithMetric("event0", CHIP_ERROR_BAD_REQUEST);
    LogErrorOnFailureWithMetric("event1", CHIP_NO_ERROR);
    LogErrorOnFailureWithMetric("event2", CHIP_ERROR_DATA_NOT_ALIGNED);
    LogErrorOnFailureWithMetric("event3", CHIP_ERROR_BUSY);

    std::vector<MetricEvent> expected = {
        MetricEvent(MetricEvent::Type::kInstantEvent, "event0", CHIP_ERROR_BAD_REQUEST),
        MetricEvent(MetricEvent::Type::kInstantEvent, "event2", CHIP_ERROR_DATA_NOT_ALIGNED),
        MetricEvent(MetricEvent::Type::kInstantEvent, "event3", CHIP_ERROR_BUSY),
    };

    EXPECT_EQ(backend.GetMetricEvents().size(), expected.size());
    EXPECT_TRUE(std::equal(backend.GetMetricEvents().begin(), backend.GetMetricEvents().end(), expected.begin(), expected.end()));
}

TEST(TestMetricEvents, TestVerifyOrDoWithMetric)
{
    MetricEventBackend backend;
    ScopedRegistration scope(backend);

    VerifyOrDoWithMetric("event0", DoubleOf(2) == 5);
    VerifyOrDoWithMetric("event1", DoubleOf(3) == 6);
    VerifyOrDoWithMetric("event2", DoubleOf(4) == 7, MATTER_LOG_METRIC("event4", 10));
    VerifyOrDoWithMetric("event3", DoubleOf(5) == 8);
    VerifyOrDoWithMetric("event5", DoubleOf(6) == 12);

    std::vector<MetricEvent> expected = {
        MetricEvent(MetricEvent::Type::kInstantEvent, "event0", false),
        MetricEvent(MetricEvent::Type::kInstantEvent, "event2", false),
        MetricEvent(MetricEvent::Type::kInstantEvent, "event4", 10),
        MetricEvent(MetricEvent::Type::kInstantEvent, "event3", false),
    };

    EXPECT_EQ(backend.GetMetricEvents().size(), expected.size());
    EXPECT_TRUE(std::equal(backend.GetMetricEvents().begin(), backend.GetMetricEvents().end(), expected.begin(), expected.end()));
}

} // namespace
