/*
 *  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,
                      Timestamp render_time,
                      int layer_id);
  bool Active() const;
  Clock* clock();

 private:
  struct DecodedFrameBase {
    int id;
    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 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;
  ~ForwardingCapturedFrameTap();

  // 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;
  VideoFrame PopFrame();

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

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

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