/*
 *  Copyright (c) 2011 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_TESTSUPPORT_FRAME_READER_H_
#define TEST_TESTSUPPORT_FRAME_READER_H_

#include <cstdio>
#include <memory>
#include <optional>
#include <string>

#include "absl/strings/string_view.h"
#include "api/scoped_refptr.h"
#include "api/video/i420_buffer.h"
#include "api/video/resolution.h"

namespace webrtc {
namespace test {

// Handles reading of I420 frames from video files.
class FrameReader {
 public:
  struct Ratio {
    int num = 1;
    int den = 1;
  };

  static constexpr Ratio kNoScale = Ratio({.num = 1, .den = 1});

  virtual ~FrameReader() {}

  // Reads and returns next frame. Returns `nullptr` if reading failed or end of
  // stream is reached.
  virtual scoped_refptr<I420Buffer> PullFrame() = 0;

  // Reads and returns next frame. `frame_num` stores unwrapped frame number
  // which can be passed to `ReadFrame` to re-read this frame later. Returns
  // `nullptr` if reading failed or end of stream is reached.
  virtual scoped_refptr<I420Buffer> PullFrame(int* frame_num) = 0;

  // Reads and returns frame specified by `frame_num`. Returns `nullptr` if
  // reading failed.
  virtual scoped_refptr<I420Buffer> ReadFrame(int frame_num) = 0;

  // Reads next frame, resizes and returns it. `frame_num` stores unwrapped
  // frame number which can be passed to `ReadFrame` to re-read this frame
  // later. `resolution` specifies resolution of the returned frame.
  // `framerate_scale` specifies frame rate scale factor. Frame rate scaling is
  // done by skipping or repeating frames.
  virtual scoped_refptr<I420Buffer> PullFrame(int* frame_num,
                                              Resolution resolution,
                                              Ratio framerate_scale) = 0;

  // Reads frame specified by `frame_num`, resizes and returns it. Returns
  // `nullptr` if reading failed.
  virtual scoped_refptr<I420Buffer> ReadFrame(int frame_num,
                                              Resolution resolution) = 0;

  // Total number of retrievable frames.
  virtual int num_frames() const = 0;
};

class YuvFrameReaderImpl : public FrameReader {
 public:
  enum class RepeatMode { kSingle, kRepeat, kPingPong };

  // Creates the frame reader for a YUV file specified by `filepath`.
  // `resolution` specifies width and height of frames in pixels. `repeat_mode`
  // specifies behaviour of the reader at reaching the end of file (stop, read
  // it over from the beginning or read in reverse order). The file is assumed
  // to exist, be readable and to contain at least 1 frame.
  YuvFrameReaderImpl(std::string filepath,
                     Resolution resolution,
                     RepeatMode repeat_mode);

  ~YuvFrameReaderImpl() override;

  virtual void Init();

  scoped_refptr<I420Buffer> PullFrame() override;

  scoped_refptr<I420Buffer> PullFrame(int* frame_num) override;

  scoped_refptr<I420Buffer> PullFrame(int* frame_num,
                                      Resolution resolution,
                                      Ratio framerate_scale) override;

  scoped_refptr<I420Buffer> ReadFrame(int frame_num) override;

  scoped_refptr<I420Buffer> ReadFrame(int frame_num,
                                      Resolution resolution) override;

  int num_frames() const override { return num_frames_; }

 protected:
  class RateScaler {
   public:
    int Skip(Ratio framerate_scale);

   private:
    std::optional<int> ticks_;
  };

  const std::string filepath_;
  Resolution resolution_;
  const RepeatMode repeat_mode_;
  int num_frames_;
  int frame_num_;
  int frame_size_bytes_;
  int header_size_bytes_;
  FILE* file_;
  RateScaler framerate_scaler_;
};

class Y4mFrameReaderImpl : public YuvFrameReaderImpl {
 public:
  // Creates the frame reader for a Y4M file specified by `filepath`.
  // `repeat_mode` specifies behaviour of the reader at reaching the end of file
  // (stop, read it over from the beginning or read in reverse order). The file
  // is assumed to exist, be readable and to contain at least 1 frame.
  Y4mFrameReaderImpl(std::string filepath, RepeatMode repeat_mode);

  void Init() override;
};

std::unique_ptr<FrameReader> CreateYuvFrameReader(std::string filepath,
                                                  Resolution resolution);

std::unique_ptr<FrameReader> CreateYuvFrameReader(
    std::string filepath,
    Resolution resolution,
    YuvFrameReaderImpl::RepeatMode repeat_mode);

std::unique_ptr<FrameReader> CreateY4mFrameReader(std::string filepath);

std::unique_ptr<FrameReader> CreateY4mFrameReader(
    std::string filepath,
    YuvFrameReaderImpl::RepeatMode repeat_mode);

// Parses video resolution from filename or path if present (e.g. "1280x720",
// "1850_1110", "cif", "qcif", "720p").
std::optional<Resolution> ParseResolutionFromFileName(absl::string_view path);

}  // namespace test
}  // namespace webrtc

#endif  // TEST_TESTSUPPORT_FRAME_READER_H_
