/*
 *  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 <limits>
#include <memory>
#include <vector>

#include "api/audio_codecs/builtin_audio_encoder_factory.h"
#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, rtc::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, rtc::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_CASE_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;
    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
