// Copyright 2019 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include <vector>

#include <fs/metrics/histograms.h>
#include <lib/fzl/time.h>
#include <lib/zx/time.h>
#include <zxtest/zxtest.h>

namespace fs_metrics {
namespace {
class FakeClock {
public:
    static zx::ticks now() { return now_; }

    static void set_now(zx::ticks ticks) { now_ = ticks; }

private:
    static zx::ticks now_;
};

struct HistogramEntry {
    uint64_t histogram_id;
    zx::duration duration;
};

zx::ticks FakeClock::now_;

class FakeHistograms {
public:
    FakeHistograms() : histogram_id_(-1) {}

    uint64_t GetHistogramId(OperationType operation, const EventOptions& options) {
        return histogram_id_;
    }

    void Record(uint64_t histogram_id, zx::duration duration) {
        collected_data_.push_back({histogram_id, duration});
    }

    void SetHistogramId(uint64_t id) { histogram_id_ = id; }

    const std::vector<HistogramEntry>& collected_data() const { return collected_data_; }

private:
    uint64_t histogram_id_;
    std::vector<HistogramEntry> collected_data_;
};

using FakeLatencyEvent = internal::LatencyEventInternal<FakeHistograms, FakeClock>;

constexpr OperationType kOperation = OperationType::kRead;
constexpr zx::ticks kStartTime = zx::ticks(5);
constexpr zx::ticks kEventTicks = zx::ticks(45);

// Cannot be constexpr because fzl::TicksToNs is not constexpr.
const zx::duration kEventDuration = fzl::TicksToNs(kEventTicks);

// Fixture for resetting time between each test.
class LatencyEventTest : public zxtest::Test {
public:
    void SetUp() override { FakeClock::set_now(kStartTime); }
    void TearDown() override { FakeClock::set_now(kStartTime); }
};

TEST_F(LatencyEventTest, RecordZero) {
    FakeHistograms histograms;
    FakeClock::set_now(zx::ticks(0));
    FakeLatencyEvent event(&histograms, kOperation);

    event.Record();

    ASSERT_TRUE(histograms.collected_data().empty());
}

TEST_F(LatencyEventTest, RecordNonZeroDelta) {
    FakeHistograms histograms;
    EventOptions options;
    FakeLatencyEvent event(&histograms, kOperation);
    *event.mutable_options() = options;

    FakeClock::set_now(kEventTicks + kStartTime);
    event.Record();

    ASSERT_EQ(histograms.collected_data().size(), 1);
    HistogramEntry entry = histograms.collected_data()[0];

    ASSERT_EQ(entry.histogram_id, histograms.GetHistogramId(kOperation, options));
    ASSERT_EQ(entry.duration, kEventDuration);
}

TEST_F(LatencyEventTest, RecordCancelledEventIsIgnored) {
    FakeHistograms histograms;
    FakeLatencyEvent event(&histograms, kOperation);

    event.Cancel();
    FakeClock::set_now(kEventTicks + kStartTime);
    event.Record();

    ASSERT_TRUE(histograms.collected_data().empty());
}

TEST_F(LatencyEventTest, RecordZeroOnDestruction) {
    FakeHistograms histograms;
    FakeClock::set_now(zx::ticks(0));

    { FakeLatencyEvent event(&histograms, kOperation); }

    ASSERT_TRUE(histograms.collected_data().empty());
}

TEST_F(LatencyEventTest, RecordNonZeroDeltaOnDestruction) {
    FakeHistograms histograms;
    EventOptions options;

    {
        FakeLatencyEvent event(&histograms, kOperation);
        *event.mutable_options() = options;

        FakeClock::set_now(kEventTicks + kStartTime);
        event.Record();
    }

    ASSERT_EQ(histograms.collected_data().size(), 1);
    auto entry = histograms.collected_data()[0];

    ASSERT_EQ(entry.histogram_id, histograms.GetHistogramId(kOperation, options));
    ASSERT_EQ(entry.duration.get(), kEventDuration.get());
}

TEST_F(LatencyEventTest, RecordCancelledEventIsIgnoredonDestruction) {
    FakeHistograms histograms;

    {
        FakeLatencyEvent event(&histograms, kOperation);

        FakeClock::set_now(kEventTicks + kStartTime);
        event.Cancel();
        event.Record();
    }

    ASSERT_TRUE(histograms.collected_data().empty());
}

} // namespace
} // namespace fs_metrics
