// Copyright 2020 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 "src/media/audio/audio_core/ring_buffer.h"

#include <lib/zx/clock.h>

#include <gtest/gtest.h>

#include "src/media/audio/lib/clock/clone_mono.h"
#include "src/media/audio/lib/clock/testing/clock_test.h"

namespace media::audio {
namespace {

const Format kDefaultFormat =
    Format::Create(fuchsia::media::AudioStreamType{
                       .sample_format = fuchsia::media::AudioSampleFormat::FLOAT,
                       .channels = 2,
                       .frames_per_second = 48000,
                   })
        .take_value();

// 10ms @ 48khz
const uint32_t kRingBufferFrameCount = 480;

class InputRingBufferTest : public ::testing::Test {
 protected:
  void SetUp() override {
    const auto& format = kDefaultFormat;
    auto timeline_function = fbl::MakeRefCounted<VersionedTimelineFunction>(
        TimelineFunction(0, zx::time(0).get(), Fixed(format.frames_per_second()).raw_value(),
                         zx::sec(1).to_nsecs()));

    auto endpoints = BaseRingBuffer::AllocateSoftwareBuffer(
        format, std::move(timeline_function), reference_clock(), kRingBufferFrameCount,
        [this]() { return safe_read_frame_; });
    ring_buffer_ = endpoints.reader;
    ASSERT_TRUE(ring_buffer());
  }

  ReadableRingBuffer* ring_buffer() const { return ring_buffer_.get(); }
  AudioClock& reference_clock() { return audio_clock_; }

  // Advance to the given time.
  void Advance(zx::time ref_time) {
    auto pts_to_frac_frame = ring_buffer_->ref_time_to_frac_presentation_frame().timeline_function;
    safe_read_frame_ = Fixed::FromRaw(pts_to_frac_frame.Apply(ref_time.get())).Floor();
  }

 private:
  std::shared_ptr<ReadableRingBuffer> ring_buffer_;

  AudioClock audio_clock_ =
      AudioClock::DeviceFixed(clock::CloneOfMonotonic(), AudioClock::kMonotonicDomain);

  int64_t safe_read_frame_ = -1;
};

class OutputRingBufferTest : public ::testing::Test {
 protected:
  void SetUp() override {
    const auto& format = kDefaultFormat;
    auto timeline_function = fbl::MakeRefCounted<VersionedTimelineFunction>(
        TimelineFunction(0, zx::time(0).get(), Fixed(format.frames_per_second()).raw_value(),
                         zx::sec(1).to_nsecs()));

    auto endpoints = BaseRingBuffer::AllocateSoftwareBuffer(
        format, std::move(timeline_function), reference_clock(), kRingBufferFrameCount,
        [this]() { return safe_write_frame_; });
    ring_buffer_ = endpoints.writer;
    ASSERT_TRUE(ring_buffer());
  }

  WritableRingBuffer* ring_buffer() const { return ring_buffer_.get(); }
  AudioClock& reference_clock() { return audio_clock_; }

  // Advance to the given time.
  void Advance(zx::time ref_time) {
    auto pts_to_frac_frame = ring_buffer_->ref_time_to_frac_presentation_frame().timeline_function;
    safe_write_frame_ = Fixed::FromRaw(pts_to_frac_frame.Apply(ref_time.get())).Floor();
  }

 private:
  std::shared_ptr<WritableRingBuffer> ring_buffer_;

  AudioClock audio_clock_ =
      AudioClock::DeviceFixed(clock::CloneOfMonotonic(), AudioClock::kMonotonicDomain);
  int64_t safe_write_frame_ = 0;
};

TEST_F(InputRingBufferTest, ReadEmptyRing) {
  Advance(zx::time(0));
  auto buffer = ring_buffer()->ReadLock(Fixed(0), 1);
  ASSERT_FALSE(buffer);
}

TEST_F(InputRingBufferTest, ReadFullyExpiredBuffer) {
  // After 20ms, the ring will have been filled twice. If we request the first 480 frames then we
  // should get no buffer returned since all those frames are now unavailable.
  Advance(zx::time(0) + zx::msec(20));
  auto buffer = ring_buffer()->ReadLock(Fixed(0), kRingBufferFrameCount);
  ASSERT_FALSE(buffer);
}

TEST_F(InputRingBufferTest, ReadNotYetAvailableBuffer) {
  // After 10ms, 480 frames will have been produced (0-479). The 480th frame is not yet available
  // so we should get no buffer.
  Advance(zx::time(0) + zx::msec(10));
  auto buffer = ring_buffer()->ReadLock(Fixed(480), 1);
  ASSERT_FALSE(buffer);
}

TEST_F(InputRingBufferTest, ReadFullyAvailableRegion) {
  // After 1ms we expect 48 frames to be available to read at the start of the buffer.
  Advance(zx::time(0) + zx::msec(1));
  auto buffer = ring_buffer()->ReadLock(Fixed(0), 48);
  ASSERT_TRUE(buffer);
  EXPECT_EQ(buffer->start().Floor(), 0u);
  EXPECT_EQ(buffer->length().Floor(), 48u);
}

TEST_F(InputRingBufferTest, ReadPartialRegion) {
  // After 1ms we expect 48 frames to be available to read at the start of the buffer. If we ask for
  // 96 we should get a buffer that contains only the 48 available frames.
  Advance(zx::time(0) + zx::msec(1));
  auto buffer = ring_buffer()->ReadLock(Fixed(0), 96);
  ASSERT_TRUE(buffer);
  EXPECT_EQ(buffer->start().Floor(), 0u);
  EXPECT_EQ(buffer->length().Floor(), 48u);
}

TEST_F(InputRingBufferTest, SkipExpiredFrames) {
  // At 11ms we'll have written the entire ring + 48 more samples, so the first 48 frames are lost.
  // Test that the returned buffer correctly skips those 48 frames.
  Advance(zx::time(0) + zx::msec(11));
  auto buffer = ring_buffer()->ReadLock(Fixed(0), 96);
  ASSERT_TRUE(buffer);
  EXPECT_EQ(buffer->start().Floor(), 48u);
  EXPECT_EQ(buffer->length().Floor(), 48u);
}

TEST_F(InputRingBufferTest, ReadAfterTruncateBufferAtEndOfTheRing) {
  // After 11ms 528 frames will have been put into the ring. We try to read the last 96 frames,
  // which spans the last 48 frames in the ring and then the first 48 frames at the start of the
  // ring again. Test our buffer is truncated for the first 48 frames requested at the end of the
  // ring.
  Advance(zx::time(0) + zx::msec(11));
  auto buffer = ring_buffer()->ReadLock(Fixed(432), 96);
  ASSERT_TRUE(buffer);
  EXPECT_EQ(buffer->start().Floor(), 432u);
  EXPECT_EQ(buffer->length().Floor(), 48u);

  // Now read that last 48 frames at the start of the ring again.
  buffer = ring_buffer()->ReadLock(Fixed(480), 48);
  ASSERT_TRUE(buffer);
  EXPECT_EQ(buffer->start().Floor(), 480u);
  EXPECT_EQ(buffer->length().Floor(), 48u);
}

TEST_F(InputRingBufferTest, ReadNegativeFrame) {
  Advance(zx::time(0));
  auto buffer = ring_buffer()->ReadLock(Fixed(-10), 10);
  ASSERT_TRUE(buffer);

  auto rb_start_address = reinterpret_cast<uintptr_t>(ring_buffer()->virt());
  auto buffer_address = reinterpret_cast<uintptr_t>(buffer->payload());
  EXPECT_EQ(buffer_address,
            rb_start_address + ((ring_buffer()->frames() - 10) * kDefaultFormat.bytes_per_frame()));
  EXPECT_EQ(buffer->start().Floor(), -10);
  EXPECT_EQ(buffer->length().Floor(), 10u);
}

TEST_F(OutputRingBufferTest, WriteEmptyRing) {
  Advance(zx::time(0));
  auto buffer = ring_buffer()->WriteLock(Fixed(0), 1);
  ASSERT_TRUE(buffer);
  ASSERT_EQ(0u, buffer->start().Floor());
  ASSERT_EQ(1u, buffer->length().Floor());
}

TEST_F(OutputRingBufferTest, WriteFullyExpiredBuffer) {
  // After 10ms the hardware will have already consumed the first kRingBufferFrameCount frames.
  // Attempting to get a buffer into that region should not be successful.
  Advance(zx::time(0) + zx::msec(10));
  auto buffer = ring_buffer()->WriteLock(Fixed(0), kRingBufferFrameCount);
  ASSERT_FALSE(buffer);
}

TEST_F(OutputRingBufferTest, WriteNotYetAvailableBuffer) {
  // Trying to get a buffer more than |kRingBufferFrameCount| frames into the future will fail as it
  // would cause use to clobber frames not yet consumed by the hardware.
  Advance(zx::time(0));
  auto buffer = ring_buffer()->WriteLock(Fixed(kRingBufferFrameCount), 1);
  ASSERT_FALSE(buffer);
}

TEST_F(OutputRingBufferTest, WriteFullyAvailableRegion) {
  // At time 0, we should be able to get a full buffer into the ring.
  Advance(zx::time(0));
  auto buffer = ring_buffer()->WriteLock(Fixed(0), kRingBufferFrameCount);
  ASSERT_TRUE(buffer);
  EXPECT_EQ(buffer->start().Floor(), 0u);
  EXPECT_EQ(buffer->length().Floor(), kRingBufferFrameCount);
}

TEST_F(OutputRingBufferTest, WritePartialRegion) {
  // After 1ms we expect 48 frames to have been consumed, so we can only get a buffer into the final
  // 48 requested frames.
  Advance(zx::time(0) + zx::msec(1));
  auto buffer = ring_buffer()->WriteLock(Fixed(0), 96);
  ASSERT_TRUE(buffer);
  EXPECT_EQ(buffer->start().Floor(), 48u);
  EXPECT_EQ(buffer->length().Floor(), 48u);
}

TEST_F(OutputRingBufferTest, WriteAfterTruncateBufferAtEndOfTheRing) {
  // After 9ms, the first 432 frames will have been consumed by hardware. Attempting to read the
  // next 96 frames will wrap around the ring, so we should only get the first 48 returned.
  Advance(zx::time(0) + zx::msec(9));
  auto buffer = ring_buffer()->WriteLock(Fixed(432), 96);
  ASSERT_TRUE(buffer);
  EXPECT_EQ(buffer->start().Floor(), 432u);
  EXPECT_EQ(buffer->length().Floor(), 48u);

  // Now read that last 48 frames at the start of the ring again.
  buffer = ring_buffer()->WriteLock(Fixed(kRingBufferFrameCount), 48);
  ASSERT_TRUE(buffer);
  EXPECT_EQ(buffer->start().Floor(), kRingBufferFrameCount);
  EXPECT_EQ(buffer->length().Floor(), 48u);
}

}  // namespace
}  // namespace media::audio
