/*
 *  Copyright (c) 2017 The WebRTC project authors. All Rights Reserved.
 *
 *  Use of this source code is governed by a BSD-style license
 *  that can be found in the LICENSE file in the root of the source
 *  tree. An additional intellectual property rights grant can be found
 *  in the file PATENTS.  All contributing project authors may
 *  be found in the AUTHORS file in the root of the source tree.
 */

#include "api/audio_codecs/builtin_audio_encoder_factory.h"

#include <limits>
#include <memory>
#include <vector>

#include "rtc_base/numerics/safe_conversions.h"
#include "test/gmock.h"
#include "test/gtest.h"

namespace webrtc {

class AudioEncoderFactoryTest
    : public ::testing::TestWithParam<rtc::scoped_refptr<AudioEncoderFactory>> {
};

TEST_P(AudioEncoderFactoryTest, SupportsAtLeastOneFormat) {
  auto factory = GetParam();
  auto supported_encoders = factory->GetSupportedEncoders();
  EXPECT_FALSE(supported_encoders.empty());
}

TEST_P(AudioEncoderFactoryTest, CanQueryAllSupportedFormats) {
  auto factory = GetParam();
  auto supported_encoders = factory->GetSupportedEncoders();
  for (const auto& spec : supported_encoders) {
    auto info = factory->QueryAudioEncoder(spec.format);
    EXPECT_TRUE(info);
  }
}

TEST_P(AudioEncoderFactoryTest, CanConstructAllSupportedEncoders) {
  auto factory = GetParam();
  auto supported_encoders = factory->GetSupportedEncoders();
  for (const auto& spec : supported_encoders) {
    auto info = factory->QueryAudioEncoder(spec.format);
    auto encoder = factory->MakeAudioEncoder(127, spec.format, absl::nullopt);
    EXPECT_TRUE(encoder);
    EXPECT_EQ(encoder->SampleRateHz(), info->sample_rate_hz);
    EXPECT_EQ(encoder->NumChannels(), info->num_channels);
    EXPECT_EQ(encoder->RtpTimestampRateHz(), spec.format.clockrate_hz);
  }
}

TEST_P(AudioEncoderFactoryTest, CanRunAllSupportedEncoders) {
  constexpr int kTestPayloadType = 127;
  auto factory = GetParam();
  auto supported_encoders = factory->GetSupportedEncoders();
  for (const auto& spec : supported_encoders) {
    auto encoder =
        factory->MakeAudioEncoder(kTestPayloadType, spec.format, absl::nullopt);
    EXPECT_TRUE(encoder);
    encoder->Reset();
    const int num_samples = rtc::checked_cast<int>(
        encoder->SampleRateHz() * encoder->NumChannels() / 100);
    rtc::Buffer out;
    rtc::BufferT<int16_t> audio;
    audio.SetData(num_samples, [](rtc::ArrayView<int16_t> audio) {
      for (size_t i = 0; i != audio.size(); ++i) {
        // Just put some numbers in there, ensure they're within range.
        audio[i] =
            static_cast<int16_t>(i & std::numeric_limits<int16_t>::max());
      }
      return audio.size();
    });
    // This is here to stop the test going forever with a broken encoder.
    constexpr int kMaxEncodeCalls = 100;
    int blocks = 0;
    for (; blocks < kMaxEncodeCalls; ++blocks) {
      AudioEncoder::EncodedInfo info = encoder->Encode(
          blocks * encoder->RtpTimestampRateHz() / 100, audio, &out);
      EXPECT_EQ(info.encoded_bytes, out.size());
      if (info.encoded_bytes > 0) {
        EXPECT_EQ(0u, info.encoded_timestamp);
        EXPECT_EQ(kTestPayloadType, info.payload_type);
        break;
      }
    }
    ASSERT_LT(blocks, kMaxEncodeCalls);
    const unsigned int next_timestamp =
        blocks * encoder->RtpTimestampRateHz() / 100;
    out.Clear();
    for (; blocks < kMaxEncodeCalls; ++blocks) {
      AudioEncoder::EncodedInfo info = encoder->Encode(
          blocks * encoder->RtpTimestampRateHz() / 100, audio, &out);
      EXPECT_EQ(info.encoded_bytes, out.size());
      if (info.encoded_bytes > 0) {
        EXPECT_EQ(next_timestamp, info.encoded_timestamp);
        EXPECT_EQ(kTestPayloadType, info.payload_type);
        break;
      }
    }
    ASSERT_LT(blocks, kMaxEncodeCalls);
  }
}

INSTANTIATE_TEST_SUITE_P(BuiltinAudioEncoderFactoryTest,
                         AudioEncoderFactoryTest,
                         ::testing::Values(CreateBuiltinAudioEncoderFactory()));

TEST(BuiltinAudioEncoderFactoryTest, SupportsTheExpectedFormats) {
  using ::testing::ElementsAreArray;
  // Check that we claim to support the formats we expect from build flags, and
  // we've ordered them correctly.
  auto factory = CreateBuiltinAudioEncoderFactory();
  auto specs = factory->GetSupportedEncoders();

  const std::vector<SdpAudioFormat> supported_formats = [&specs] {
    std::vector<SdpAudioFormat> formats;
    formats.reserve(specs.size());
    for (const auto& spec : specs) {
      formats.push_back(spec.format);
    }
    return formats;
  }();

  const std::vector<SdpAudioFormat> expected_formats = {
#ifdef WEBRTC_CODEC_OPUS
    {"opus", 48000, 2, {{"minptime", "10"}, {"useinbandfec", "1"}}},
#endif
#if defined(WEBRTC_CODEC_ISAC) || defined(WEBRTC_CODEC_ISACFX)
    {"isac", 16000, 1},
#endif
#ifdef WEBRTC_CODEC_ISAC
    {"isac", 32000, 1},
#endif
    {"G722", 8000, 1},
#ifdef WEBRTC_CODEC_ILBC
    {"ilbc", 8000, 1},
#endif
    {"pcmu", 8000, 1},
    {"pcma", 8000, 1}
  };

  ASSERT_THAT(supported_formats, ElementsAreArray(expected_formats));
}
}  // namespace webrtc
