/*
 *  Copyright (c) 2019 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 "pc/video_rtp_track_source.h"

#include <optional>

#include "api/make_ref_counted.h"
#include "api/scoped_refptr.h"
#include "api/units/timestamp.h"
#include "api/video/color_space.h"
#include "api/video/encoded_image.h"
#include "api/video/recordable_encoded_frame.h"
#include "api/video/video_codec_type.h"
#include "api/video/video_rotation.h"
#include "api/video/video_sink_interface.h"
#include "test/gmock.h"
#include "test/gtest.h"

namespace webrtc {
namespace {

class MockCallback : public VideoRtpTrackSource::Callback {
 public:
  MOCK_METHOD(void, OnGenerateKeyFrame, (), (override));
  MOCK_METHOD(void, OnEncodedSinkEnabled, (bool), (override));
};

class MockSink : public VideoSinkInterface<RecordableEncodedFrame> {
 public:
  MOCK_METHOD(void, OnFrame, (const RecordableEncodedFrame&), (override));
};

scoped_refptr<VideoRtpTrackSource> MakeSource(
    VideoRtpTrackSource::Callback* callback) {
  return make_ref_counted<VideoRtpTrackSource>(callback);
}

TEST(VideoRtpTrackSourceTest, CreatesWithRemoteAtttributeSet) {
  EXPECT_TRUE(MakeSource(nullptr)->remote());
}

TEST(VideoRtpTrackSourceTest, EnablesEncodingOutputOnAddingSink) {
  MockCallback mock_callback;
  EXPECT_CALL(mock_callback, OnGenerateKeyFrame).Times(0);
  auto source = MakeSource(&mock_callback);
  MockSink sink;
  EXPECT_CALL(mock_callback, OnEncodedSinkEnabled(true));
  source->AddEncodedSink(&sink);
}

TEST(VideoRtpTrackSourceTest, EnablesEncodingOutputOnceOnAddingTwoSinks) {
  MockCallback mock_callback;
  EXPECT_CALL(mock_callback, OnGenerateKeyFrame).Times(0);
  auto source = MakeSource(&mock_callback);
  MockSink sink;
  EXPECT_CALL(mock_callback, OnEncodedSinkEnabled(true)).Times(1);
  source->AddEncodedSink(&sink);
  MockSink sink2;
  source->AddEncodedSink(&sink2);
}

TEST(VideoRtpTrackSourceTest, DisablesEncodingOutputOnOneSinkRemoved) {
  MockCallback mock_callback;
  EXPECT_CALL(mock_callback, OnGenerateKeyFrame).Times(0);
  EXPECT_CALL(mock_callback, OnEncodedSinkEnabled(true));
  EXPECT_CALL(mock_callback, OnEncodedSinkEnabled(false)).Times(0);
  auto source = MakeSource(&mock_callback);
  MockSink sink;
  source->AddEncodedSink(&sink);
  testing::Mock::VerifyAndClearExpectations(&mock_callback);
  EXPECT_CALL(mock_callback, OnEncodedSinkEnabled(false));
  source->RemoveEncodedSink(&sink);
}

TEST(VideoRtpTrackSourceTest, DisablesEncodingOutputOnLastSinkRemoved) {
  MockCallback mock_callback;
  EXPECT_CALL(mock_callback, OnGenerateKeyFrame).Times(0);
  EXPECT_CALL(mock_callback, OnEncodedSinkEnabled(true));
  auto source = MakeSource(&mock_callback);
  MockSink sink;
  source->AddEncodedSink(&sink);
  MockSink sink2;
  source->AddEncodedSink(&sink2);
  source->RemoveEncodedSink(&sink);
  testing::Mock::VerifyAndClearExpectations(&mock_callback);
  EXPECT_CALL(mock_callback, OnEncodedSinkEnabled(false));
  source->RemoveEncodedSink(&sink2);
}

TEST(VideoRtpTrackSourceTest, GeneratesKeyFrameWhenRequested) {
  MockCallback mock_callback;
  auto source = MakeSource(&mock_callback);
  EXPECT_CALL(mock_callback, OnGenerateKeyFrame);
  source->GenerateKeyFrame();
}

TEST(VideoRtpTrackSourceTest, NoCallbacksAfterClearedCallback) {
  testing::StrictMock<MockCallback> mock_callback;
  auto source = MakeSource(&mock_callback);
  source->ClearCallback();
  MockSink sink;
  source->AddEncodedSink(&sink);
  source->GenerateKeyFrame();
  source->RemoveEncodedSink(&sink);
}

class TestFrame : public RecordableEncodedFrame {
 public:
  scoped_refptr<const EncodedImageBufferInterface> encoded_buffer()
      const override {
    return nullptr;
  }
  std::optional<ColorSpace> color_space() const override {
    return std::nullopt;
  }
  std::optional<VideoRotation> video_rotation() const override {
    return std::nullopt;
  }
  VideoCodecType codec() const override { return kVideoCodecGeneric; }
  bool is_key_frame() const override { return false; }
  EncodedResolution resolution() const override {
    return EncodedResolution{.width = 0, .height = 0};
  }
  Timestamp render_time() const override { return Timestamp::Zero(); }
};

TEST(VideoRtpTrackSourceTest, BroadcastsFrames) {
  auto source = MakeSource(nullptr);
  MockSink sink;
  source->AddEncodedSink(&sink);
  MockSink sink2;
  source->AddEncodedSink(&sink2);
  TestFrame frame;
  EXPECT_CALL(sink, OnFrame);
  EXPECT_CALL(sink2, OnFrame);
  source->BroadcastRecordableEncodedFrame(frame);
}

}  // namespace
}  // namespace webrtc
