/*
 *  Copyright 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.
 */
#ifndef TEST_SCENARIO_VIDEO_FRAME_MATCHER_H_
#define TEST_SCENARIO_VIDEO_FRAME_MATCHER_H_

#include <deque>
#include <map>
#include <memory>
#include <set>
#include <string>
#include <vector>

#include "api/units/timestamp.h"
#include "api/video/video_frame.h"
#include "api/video/video_sink_interface.h"
#include "api/video/video_source_interface.h"
#include "rtc_base/ref_counted_object.h"
#include "rtc_base/task_queue_for_test.h"
#include "system_wrappers/include/clock.h"
#include "test/scenario/performance_stats.h"

namespace webrtc {
namespace test {

class VideoFrameMatcher {
 public:
  explicit VideoFrameMatcher(
      std::vector<std::function<void(const VideoFramePair&)>>
          frame_pair_handlers);
  ~VideoFrameMatcher();
  void RegisterLayer(int layer_id);
  void OnCapturedFrame(const VideoFrame& frame, Timestamp at_time);
  void OnDecodedFrame(const VideoFrame& frame,
                      int layer_id,
                      Timestamp render_time,
                      Timestamp at_time);
  bool Active() const;

 private:
  struct DecodedFrameBase {
    int id;
    Timestamp decoded_time = Timestamp::PlusInfinity();
    Timestamp render_time = Timestamp::PlusInfinity();
    rtc::scoped_refptr<VideoFrameBuffer> frame;
    rtc::scoped_refptr<VideoFrameBuffer> thumb;
    int repeat_count = 0;
  };
  using DecodedFrame = rtc::RefCountedObject<DecodedFrameBase>;
  struct CapturedFrame {
    int id;
    Timestamp capture_time = Timestamp::PlusInfinity();
    rtc::scoped_refptr<VideoFrameBuffer> frame;
    rtc::scoped_refptr<VideoFrameBuffer> thumb;
    double best_score = INFINITY;
    rtc::scoped_refptr<DecodedFrame> best_decode;
    bool matched = false;
  };
  struct VideoLayer {
    int layer_id;
    std::deque<CapturedFrame> captured_frames;
    rtc::scoped_refptr<DecodedFrame> last_decode;
    int next_decoded_id = 1;
  };
  void HandleMatch(CapturedFrame captured, int layer_id);
  void Finalize();
  int next_capture_id_ = 1;
  std::vector<std::function<void(const VideoFramePair&)>> frame_pair_handlers_;
  std::map<int, VideoLayer> layers_;
  TaskQueueForTest task_queue_;
};

class CapturedFrameTap : public rtc::VideoSinkInterface<VideoFrame> {
 public:
  CapturedFrameTap(Clock* clock, VideoFrameMatcher* matcher);
  CapturedFrameTap(CapturedFrameTap&) = delete;
  CapturedFrameTap& operator=(CapturedFrameTap&) = delete;

  void OnFrame(const VideoFrame& frame) override;
  void OnDiscardedFrame() override;

 private:
  Clock* const clock_;
  VideoFrameMatcher* const matcher_;
  int discarded_count_ = 0;
};

class ForwardingCapturedFrameTap
    : public rtc::VideoSinkInterface<VideoFrame>,
      public rtc::VideoSourceInterface<VideoFrame> {
 public:
  ForwardingCapturedFrameTap(Clock* clock,
                             VideoFrameMatcher* matcher,
                             rtc::VideoSourceInterface<VideoFrame>* source);
  ForwardingCapturedFrameTap(ForwardingCapturedFrameTap&) = delete;
  ForwardingCapturedFrameTap& operator=(ForwardingCapturedFrameTap&) = delete;

  // VideoSinkInterface interface
  void OnFrame(const VideoFrame& frame) override;
  void OnDiscardedFrame() override;

  // VideoSourceInterface interface
  void AddOrUpdateSink(VideoSinkInterface<VideoFrame>* sink,
                       const rtc::VideoSinkWants& wants) override;
  void RemoveSink(VideoSinkInterface<VideoFrame>* sink) override;

 private:
  Clock* const clock_;
  VideoFrameMatcher* const matcher_;
  rtc::VideoSourceInterface<VideoFrame>* const source_;
  VideoSinkInterface<VideoFrame>* sink_ = nullptr;
  int discarded_count_ = 0;
};

class DecodedFrameTap : public rtc::VideoSinkInterface<VideoFrame> {
 public:
  DecodedFrameTap(Clock* clock, VideoFrameMatcher* matcher, int layer_id);
  // VideoSinkInterface interface
  void OnFrame(const VideoFrame& frame) override;

 private:
  Clock* const clock_;
  VideoFrameMatcher* const matcher_;
  int layer_id_;
};
}  // namespace test
}  // namespace webrtc
#endif  // TEST_SCENARIO_VIDEO_FRAME_MATCHER_H_
