// Copyright 2023 The Dawn & Tint Authors
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// 1. Redistributions of source code must retain the above copyright notice, this
//    list of conditions and the following disclaimer.
//
// 2. Redistributions in binary form must reproduce the above copyright notice,
//    this list of conditions and the following disclaimer in the documentation
//    and/or other materials provided with the distribution.
//
// 3. Neither the name of the copyright holder nor the names of its
//    contributors may be used to endorse or promote products derived from
//    this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

#include <memory>

#include "partition_alloc/pointers/raw_ptr.h"
#include "src/dawn/platform/metrics/HistogramMacros.h"
#include "src/dawn/tests/DawnTest.h"

namespace dawn {
namespace {

using ::testing::_;
using ::testing::InSequence;
using ::testing::NiceMock;

class DawnHistogramMockPlatform : public dawn::platform::Platform {
  public:
    void SetTime(double time) { mTime = time; }

    double MonotonicallyIncreasingTime() override { return mTime; }

    MOCK_METHOD(void,
                HistogramCustomCounts,
                (const char* name, int sample, int min, int max, int bucketCount),
                (override));

    MOCK_METHOD(void,
                HistogramCustomCountsHPC,
                (const char* name, int sample, int min, int max, int bucketCount),
                (override));

    MOCK_METHOD(void,
                HistogramEnumeration,
                (const char* name, int sample, int boundaryValue),
                (override));

    MOCK_METHOD(void, HistogramSparse, (const char* name, int sample), (override));

    MOCK_METHOD(void, HistogramBoolean, (const char* name, bool sample), (override));

  private:
    double mTime = 0.0;
};

class HistogramTests : public DawnTest {
  protected:
    void SetUp() override { DawnTest::SetUp(); }

    std::unique_ptr<platform::Platform> CreateTestPlatform() override {
        auto p = std::make_unique<NiceMock<DawnHistogramMockPlatform>>();
        mMockPlatform = p.get();
        return p;
    }

    raw_ptr<NiceMock<DawnHistogramMockPlatform>> mMockPlatform;
};

TEST_P(HistogramTests, Times) {
    InSequence seq;
    EXPECT_CALL(*mMockPlatform, HistogramCustomCounts("times", 1, _, _, _));
    EXPECT_CALL(*mMockPlatform, HistogramCustomCounts("medium_times", 2, _, _, _));
    EXPECT_CALL(*mMockPlatform, HistogramCustomCounts("long_times", 3, _, _, _));
    EXPECT_CALL(*mMockPlatform, HistogramCustomCounts("long_times_100", 4, _, _, _));
    EXPECT_CALL(*mMockPlatform, HistogramCustomCounts("custom_times", 5, 0, 10, 42));
    EXPECT_CALL(*mMockPlatform,
                HistogramCustomCountsHPC("custom_microsecond_times", 6, 0, 100, 420));

    DAWN_HISTOGRAM_TIMES(mMockPlatform, "times", 1);
    DAWN_HISTOGRAM_MEDIUM_TIMES(mMockPlatform, "medium_times", 2);
    DAWN_HISTOGRAM_LONG_TIMES(mMockPlatform, "long_times", 3);
    DAWN_HISTOGRAM_LONG_TIMES_100(mMockPlatform, "long_times_100", 4);
    DAWN_HISTOGRAM_CUSTOM_TIMES(mMockPlatform, "custom_times", 5, 0, 10, 42);
    DAWN_HISTOGRAM_CUSTOM_MICROSECOND_TIMES(mMockPlatform, "custom_microsecond_times", 6, 0, 100,
                                            420);
}

TEST_P(HistogramTests, Percentage) {
    InSequence seq;
    EXPECT_CALL(*mMockPlatform, HistogramEnumeration("percentage", 0, 101));
    EXPECT_CALL(*mMockPlatform, HistogramEnumeration("percentage", 42, 101));
    EXPECT_CALL(*mMockPlatform, HistogramEnumeration("percentage", 100, 101));

    DAWN_HISTOGRAM_PERCENTAGE(mMockPlatform, "percentage", 0);
    DAWN_HISTOGRAM_PERCENTAGE(mMockPlatform, "percentage", 42);
    DAWN_HISTOGRAM_PERCENTAGE(mMockPlatform, "percentage", 100);
}

TEST_P(HistogramTests, Boolean) {
    InSequence seq;
    EXPECT_CALL(*mMockPlatform, HistogramBoolean("boolean", false));
    EXPECT_CALL(*mMockPlatform, HistogramBoolean("boolean", true));

    DAWN_HISTOGRAM_BOOLEAN(mMockPlatform, "boolean", false);
    DAWN_HISTOGRAM_BOOLEAN(mMockPlatform, "boolean", true);
}

TEST_P(HistogramTests, Enumeration) {
    enum Animal { Dog, Cat, Bear, Count };

    InSequence seq;
    EXPECT_CALL(*mMockPlatform, HistogramEnumeration("animal", Animal::Dog, Animal::Count));
    EXPECT_CALL(*mMockPlatform, HistogramEnumeration("animal", Animal::Cat, Animal::Count));
    EXPECT_CALL(*mMockPlatform, HistogramEnumeration("animal", Animal::Bear, Animal::Count));

    DAWN_HISTOGRAM_ENUMERATION(mMockPlatform, "animal", Animal::Dog, Animal::Count);
    DAWN_HISTOGRAM_ENUMERATION(mMockPlatform, "animal", Animal::Cat, Animal::Count);
    DAWN_HISTOGRAM_ENUMERATION(mMockPlatform, "animal", Animal::Bear, Animal::Count);
}

TEST_P(HistogramTests, Memory) {
    InSequence seq;
    EXPECT_CALL(*mMockPlatform, HistogramCustomCounts("kb", 1, _, _, _));
    EXPECT_CALL(*mMockPlatform, HistogramCustomCounts("mb", 2, _, _, _));

    DAWN_HISTOGRAM_MEMORY_KB(mMockPlatform, "kb", 1);
    DAWN_HISTOGRAM_MEMORY_MB(mMockPlatform, "mb", 2);
}

TEST_P(HistogramTests, Sparse) {
    InSequence seq;
    EXPECT_CALL(*mMockPlatform, HistogramSparse("sparse", 1));
    EXPECT_CALL(*mMockPlatform, HistogramSparse("sparse", 2));

    DAWN_HISTOGRAM_SPARSE(mMockPlatform, "sparse", 1);
    DAWN_HISTOGRAM_SPARSE(mMockPlatform, "sparse", 2);
}

TEST_P(HistogramTests, ScopedTimer) {
    InSequence seq;
    EXPECT_CALL(*mMockPlatform, HistogramCustomCounts("timer0", 2'500, _, _, _));
    EXPECT_CALL(*mMockPlatform, HistogramCustomCounts("timer1", 15'500, _, _, _));
    EXPECT_CALL(*mMockPlatform, HistogramCustomCounts("timer4", 2'500, _, _, _));
    EXPECT_CALL(*mMockPlatform, HistogramCustomCounts("timer3", 6'000, _, _, _));
    EXPECT_CALL(*mMockPlatform, HistogramCustomCountsHPC("timer5", 1'500'000, _, _, _));

    {
        mMockPlatform->SetTime(1.0);
        SCOPED_DAWN_HISTOGRAM_TIMER(mMockPlatform, "timer0");
        mMockPlatform->SetTime(3.5);
    }
    {
        mMockPlatform->SetTime(10.0);
        SCOPED_DAWN_HISTOGRAM_LONG_TIMER(mMockPlatform, "timer1");
        mMockPlatform->SetTime(25.5);
    }
    {
        mMockPlatform->SetTime(1.0);
        SCOPED_DAWN_HISTOGRAM_TIMER(mMockPlatform, "timer3");
        mMockPlatform->SetTime(4.5);
        SCOPED_DAWN_HISTOGRAM_LONG_TIMER(mMockPlatform, "timer4");
        mMockPlatform->SetTime(7.0);
    }
    {
        mMockPlatform->SetTime(1.0);
        SCOPED_DAWN_HISTOGRAM_TIMER_MICROS(mMockPlatform, "timer5");
        mMockPlatform->SetTime(2.5);
    }
}

DAWN_INSTANTIATE_TEST(HistogramTests,
                      D3D11Backend(),
                      D3D12Backend(),
                      MetalBackend(),
                      NullBackend(),
                      OpenGLBackend(),
                      OpenGLESBackend(),
                      VulkanBackend(),
                      WebGPUBackend());

}  // namespace
}  // namespace dawn
