/*
 *  Copyright (c) 2018 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 <memory>
#include <vector>

#include "api/video_codecs/sdp_video_format.h"
#include "api/video_codecs/video_decoder.h"
#include "api/video_codecs/video_decoder_factory.h"
#include "api/video_codecs/video_encoder.h"
#include "api/video_codecs/video_encoder_factory.h"
#if defined(WEBRTC_ANDROID)
#include "modules/video_coding/codecs/test/android_codec_factory_helper.h"
#elif defined(WEBRTC_IOS)
#include "modules/video_coding/codecs/test/objc_codec_factory_helper.h"
#endif
#include "test/gtest.h"
#include "test/video_codec_settings.h"

namespace webrtc {
namespace test {

namespace {

int32_t InitEncoder(VideoCodecType codec_type, VideoEncoder* encoder) {
  VideoCodec codec;
  CodecSettings(codec_type, &codec);
  codec.width = 640;
  codec.height = 480;
  codec.maxFramerate = 30;
  RTC_CHECK(encoder);
  return encoder->InitEncode(&codec, 1 /* number_of_cores */,
                             1200 /* max_payload_size */);
}

int32_t InitDecoder(VideoCodecType codec_type, VideoDecoder* decoder) {
  VideoCodec codec;
  CodecSettings(codec_type, &codec);
  codec.width = 640;
  codec.height = 480;
  codec.maxFramerate = 30;
  RTC_CHECK(decoder);
  return decoder->InitDecode(&codec, 1 /* number_of_cores */);
}

}  // namespace

class VideoEncoderDecoderInstantiationTest
    : public ::testing::Test,
      public ::testing::WithParamInterface<::testing::tuple<int, int>> {
 protected:
  VideoEncoderDecoderInstantiationTest()
      : vp8_format_("VP8"),
        vp9_format_("VP9"),
        h264cbp_format_("H264"),
        num_encoders_(::testing::get<0>(GetParam())),
        num_decoders_(::testing::get<1>(GetParam())) {
#if defined(WEBRTC_ANDROID)
    InitializeAndroidObjects();
    encoder_factory_ = CreateAndroidEncoderFactory();
    decoder_factory_ = CreateAndroidDecoderFactory();
#elif defined(WEBRTC_IOS)
    encoder_factory_ = CreateObjCEncoderFactory();
    decoder_factory_ = CreateObjCDecoderFactory();
#else
    RTC_NOTREACHED() << "Only support Android and iOS.";
#endif
  }

  ~VideoEncoderDecoderInstantiationTest() {
    for (auto& encoder : encoders_) {
      encoder->Release();
    }
    for (auto& decoder : decoders_) {
      decoder->Release();
    }
  }

  const SdpVideoFormat vp8_format_;
  const SdpVideoFormat vp9_format_;
  const SdpVideoFormat h264cbp_format_;
  std::unique_ptr<VideoEncoderFactory> encoder_factory_;
  std::unique_ptr<VideoDecoderFactory> decoder_factory_;

  const int num_encoders_;
  const int num_decoders_;
  std::vector<std::unique_ptr<VideoEncoder>> encoders_;
  std::vector<std::unique_ptr<VideoDecoder>> decoders_;
};

INSTANTIATE_TEST_SUITE_P(MultipleEncoders,
                         VideoEncoderDecoderInstantiationTest,
                         ::testing::Combine(::testing::Range(1, 4),
                                            ::testing::Range(1, 2)));

INSTANTIATE_TEST_SUITE_P(MultipleDecoders,
                         VideoEncoderDecoderInstantiationTest,
                         ::testing::Combine(::testing::Range(1, 2),
                                            ::testing::Range(1, 9)));

INSTANTIATE_TEST_SUITE_P(MultipleEncodersDecoders,
                         VideoEncoderDecoderInstantiationTest,
                         ::testing::Combine(::testing::Range(1, 4),
                                            ::testing::Range(1, 9)));

// TODO(brandtr): Check that the factories actually support the codecs before
// trying to instantiate. Currently, we will just crash with a Java exception
// if the factory does not support the codec.
TEST_P(VideoEncoderDecoderInstantiationTest, DISABLED_InstantiateVp8Codecs) {
  for (int i = 0; i < num_encoders_; ++i) {
    std::unique_ptr<VideoEncoder> encoder =
        encoder_factory_->CreateVideoEncoder(vp8_format_);
    EXPECT_EQ(0, InitEncoder(kVideoCodecVP8, encoder.get()));
    encoders_.emplace_back(std::move(encoder));
  }

  for (int i = 0; i < num_decoders_; ++i) {
    std::unique_ptr<VideoDecoder> decoder =
        decoder_factory_->CreateVideoDecoder(vp8_format_);
    EXPECT_EQ(0, InitDecoder(kVideoCodecVP8, decoder.get()));
    decoders_.emplace_back(std::move(decoder));
  }
}

TEST_P(VideoEncoderDecoderInstantiationTest,
       DISABLED_InstantiateH264CBPCodecs) {
  for (int i = 0; i < num_encoders_; ++i) {
    std::unique_ptr<VideoEncoder> encoder =
        encoder_factory_->CreateVideoEncoder(h264cbp_format_);
    EXPECT_EQ(0, InitEncoder(kVideoCodecH264, encoder.get()));
    encoders_.emplace_back(std::move(encoder));
  }

  for (int i = 0; i < num_decoders_; ++i) {
    std::unique_ptr<VideoDecoder> decoder =
        decoder_factory_->CreateVideoDecoder(h264cbp_format_);
    EXPECT_EQ(0, InitDecoder(kVideoCodecH264, decoder.get()));
    decoders_.emplace_back(std::move(decoder));
  }
}

}  // namespace test
}  // namespace webrtc
