/*
 *  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 "sdk/android/native_api/video/video_source.h"

#include <jni.h>

#include <optional>

#include "api/make_ref_counted.h"
#include "api/media_stream_interface.h"
#include "api/scoped_refptr.h"
#include "api/video/recordable_encoded_frame.h"
#include "api/video/video_frame.h"
#include "api/video/video_sink_interface.h"
#include "api/video/video_source_interface.h"
#include "rtc_base/thread.h"
#include "sdk/android/native_api/jni/scoped_java_ref.h"
#include "sdk/android/src/jni/android_video_track_source.h"
#include "sdk/android/src/jni/native_capturer_observer.h"

namespace webrtc {

namespace {

// Hides full jni::AndroidVideoTrackSource interface and provides an instance of
// NativeCapturerObserver associated with the video source. Does not extend
// AndroidVideoTrackSource to avoid diamond inheritance on
// VideoTrackSourceInterface.
class JavaVideoTrackSourceImpl : public JavaVideoTrackSourceInterface {
 public:
  JavaVideoTrackSourceImpl(JNIEnv* env,
                           Thread* signaling_thread,
                           bool is_screencast,
                           bool align_timestamps)
      : android_video_track_source_(
            make_ref_counted<jni::AndroidVideoTrackSource>(signaling_thread,
                                                           env,
                                                           is_screencast,
                                                           align_timestamps)),
        native_capturer_observer_(jni::CreateJavaNativeCapturerObserver(
            env,
            android_video_track_source_)) {}

  ScopedJavaLocalRef<jobject> GetJavaVideoCapturerObserver(
      JNIEnv* env) override {
    return ScopedJavaLocalRef<jobject>(env, native_capturer_observer_);
  }

  // Delegate VideoTrackSourceInterface methods to android_video_track_source_.
  void RegisterObserver(ObserverInterface* observer) override {
    android_video_track_source_->RegisterObserver(observer);
  }

  void UnregisterObserver(ObserverInterface* observer) override {
    android_video_track_source_->UnregisterObserver(observer);
  }

  SourceState state() const override {
    return android_video_track_source_->state();
  }

  bool remote() const override { return android_video_track_source_->remote(); }

  void AddOrUpdateSink(VideoSinkInterface<VideoFrame>* sink,
                       const VideoSinkWants& wants) override {
    // The method is defined private in the implementation so we have to access
    // it through the interface...
    static_cast<VideoTrackSourceInterface*>(android_video_track_source_.get())
        ->AddOrUpdateSink(sink, wants);
  }

  void RemoveSink(VideoSinkInterface<VideoFrame>* sink) override {
    // The method is defined private in the implementation so we have to access
    // it through the interface...
    static_cast<VideoTrackSourceInterface*>(android_video_track_source_.get())
        ->RemoveSink(sink);
  }

  bool is_screencast() const override {
    return android_video_track_source_->is_screencast();
  }

  std::optional<bool> needs_denoising() const override {
    return android_video_track_source_->needs_denoising();
  }

  bool GetStats(Stats* stats) override {
    // The method is defined private in the implementation so we have to access
    // it through the interface...
    return static_cast<VideoTrackSourceInterface*>(
               android_video_track_source_.get())
        ->GetStats(stats);
  }

 private:
  // Encoded sinks not implemented for JavaVideoTrackSourceImpl.
  bool SupportsEncodedOutput() const override { return false; }
  void GenerateKeyFrame() override {}
  void AddEncodedSink(
      VideoSinkInterface<RecordableEncodedFrame>* sink) override {}
  void RemoveEncodedSink(
      VideoSinkInterface<RecordableEncodedFrame>* sink) override {}

  scoped_refptr<jni::AndroidVideoTrackSource> android_video_track_source_;
  ScopedJavaGlobalRef<jobject> native_capturer_observer_;
};

}  // namespace

scoped_refptr<JavaVideoTrackSourceInterface> CreateJavaVideoSource(
    JNIEnv* jni,
    Thread* signaling_thread,
    bool is_screencast,
    bool align_timestamps) {
  return make_ref_counted<JavaVideoTrackSourceImpl>(
      jni, signaling_thread, is_screencast, align_timestamps);
}

}  // namespace webrtc
