// Copyright 2022 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/lib/processing/point_sampler.h"

#include <cstdint>
#include <utility>
#include <vector>

#include <gmock/gmock.h>
#include <gtest/gtest.h>

#include "ffl/fixed.h"
#include "fidl/fuchsia.mediastreams/cpp/wire_types.h"
#include "src/media/audio/lib/format2/fixed.h"
#include "src/media/audio/lib/format2/sample_converter.h"
#include "src/media/audio/lib/processing/gain.h"

namespace media_audio {
namespace {

using ::fuchsia_mediastreams::wire::AudioSampleFormat;
using ::testing::IsNull;
using ::testing::NotNull;

constexpr std::pair<uint32_t, uint32_t> kChannelConfigs[] = {
    {1, 1}, {1, 2}, {1, 3}, {1, 4}, {2, 1}, {2, 2}, {2, 3}, {2, 4}, {3, 1},
    {3, 2}, {3, 3}, {4, 1}, {4, 2}, {4, 4}, {5, 5}, {6, 6}, {7, 7}, {8, 8},
};

constexpr uint32_t kFrameRates[] = {
    8000, 11025, 16000, 22050, 24000, 32000, 44100, 48000, 88200, 96000, 176400, 192000,
};

constexpr AudioSampleFormat kSampleFormats[] = {
    AudioSampleFormat::kUnsigned8,
    AudioSampleFormat::kSigned16,
    AudioSampleFormat::kSigned24In32,
    AudioSampleFormat::kFloat,
};

Format CreateFormat(uint32_t channel_count, uint32_t frame_rate, AudioSampleFormat sample_format) {
  return Format::CreateOrDie({sample_format, channel_count, frame_rate});
}

TEST(PointSamplerTest, CreateWithValidConfigs) {
  for (const auto& [source_channel_count, dest_channel_count] : kChannelConfigs) {
    for (const auto& frame_rate : kFrameRates) {
      for (const auto& sample_format : kSampleFormats) {
        EXPECT_THAT(PointSampler::Create(
                        CreateFormat(source_channel_count, frame_rate, sample_format),
                        CreateFormat(dest_channel_count, frame_rate, AudioSampleFormat::kFloat)),
                    NotNull());
      }
    }
  }
}

TEST(PointSamplerTest, CreateFailsWithMismatchingFrameRates) {
  const AudioSampleFormat sample_format = AudioSampleFormat::kFloat;
  for (const auto& [source_channel_count, dest_channel_count] : kChannelConfigs) {
    for (const auto& source_frame_rate : kFrameRates) {
      for (const auto& dest_frame_rate : kFrameRates) {
        if (source_frame_rate != dest_frame_rate) {
          EXPECT_THAT(PointSampler::Create(
                          CreateFormat(source_channel_count, source_frame_rate, sample_format),
                          CreateFormat(dest_channel_count, dest_frame_rate, sample_format)),
                      IsNull());
        }
      }
    }
  }
}

TEST(PointSamplerTest, CreateFailsWithUnsupportedChannelConfigs) {
  const std::pair<uint32_t, uint32_t> unsupported_channel_configs[] = {
      {1, 5}, {1, 8}, {1, 9}, {2, 5}, {2, 8}, {2, 9}, {3, 5},
      {3, 8}, {3, 9}, {4, 5}, {4, 7}, {4, 9}, {5, 1}, {9, 1},
  };
  for (const auto& [source_channel_count, dest_channel_count] : unsupported_channel_configs) {
    for (const auto& frame_rate : kFrameRates) {
      for (const auto& sample_format : kSampleFormats) {
        EXPECT_THAT(PointSampler::Create(
                        CreateFormat(source_channel_count, frame_rate, sample_format),
                        CreateFormat(dest_channel_count, frame_rate, AudioSampleFormat::kFloat)),
                    IsNull());
      }
    }
  }
}

TEST(PointSamplerTest, CreateFailsWithUnsupportedDestSampleFormats) {
  const uint32_t frame_rate = 44100;
  for (const auto& [source_channel_count, dest_channel_count] : kChannelConfigs) {
    for (const auto& source_sample_format : kSampleFormats) {
      for (const auto& dest_sample_format : kSampleFormats) {
        if (dest_sample_format != fuchsia_mediastreams::AudioSampleFormat::kFloat) {
          EXPECT_THAT(PointSampler::Create(
                          CreateFormat(source_channel_count, frame_rate, source_sample_format),
                          CreateFormat(dest_channel_count, frame_rate, dest_sample_format)),
                      IsNull());
        }
      }
    }
  }
}

class PassthroughTest : public ::testing::TestWithParam<Fixed> {};

TEST_P(PassthroughTest, PassthroughMono) {
  // Create mono sampler.
  auto mono_sampler = PointSampler::Create(CreateFormat(1, 48000, AudioSampleFormat::kUnsigned8),
                                           CreateFormat(1, 48000, AudioSampleFormat::kFloat));
  EXPECT_EQ(mono_sampler->pos_filter_length(), Fixed::FromRaw(kFracHalfFrame + 1));
  EXPECT_EQ(mono_sampler->neg_filter_length(), kHalfFrame);

  // Process with unity gain.
  const std::vector<uint8_t> source_samples = {0x00, 0xFF, 0x27, 0xCD, 0x7F, 0x80, 0xA6, 0x6D};
  const int64_t frame_count = static_cast<int64_t>(source_samples.size());

  Fixed source_offset = GetParam();
  Sampler::Source source = {source_samples.data(), &source_offset, frame_count};

  Sampler::Gain gain = {.type = GainType::kUnity, .scale = kUnityGainScale};

  std::vector<float> dest_samples(source_samples.size(), 0.0f);
  int64_t dest_offset = 0;
  Sampler::Dest dest = {dest_samples.data(), &dest_offset, frame_count};

  mono_sampler->Process(source, dest, gain, /*accumulate=*/false);
  for (int i = 0; i < frame_count; ++i) {
    EXPECT_FLOAT_EQ(SampleConverter<uint8_t>::ToFloat(source_samples[i]), dest_samples[i]);
  }
}

INSTANTIATE_TEST_SUITE_P(PointSamplerTest, PassthroughTest,
                         testing::Values(-kHalfFrame, Fixed(0),
                                         ffl::FromRaw<kPtsFractionalBits>(kFracHalfFrame - 1)));

// TODO(fxbug.dev/87651): Move the rest of the `media::audio::mixer::PointSampler` unit tests once
// `media::audio::mixer::Mixer` code is fully migrated.

}  // namespace
}  // namespace media_audio
