/*
 *  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 <stdio.h>

#include <string>

#include "api/scoped_refptr.h"
#include "api/video/i420_buffer.h"
#include "common_video/libyuv/include/webrtc_libyuv.h"
#include "rtc_base/logging.h"
#include "rtc_base/strings/string_builder.h"
#include "test/testsupport/file_utils.h"
#include "test/testsupport/frame_reader.h"

namespace webrtc {
namespace test {
namespace {
constexpr int kFrameHeaderSize = 6;  // "FRAME\n"
}  // namespace

void ParseY4mHeader(std::string filepath,
                    Resolution* resolution,
                    int* header_size) {
  FILE* file = fopen(filepath.c_str(), "r");
  RTC_CHECK(file != NULL) << "Cannot open " << filepath;

  // Length of Y4M header is technically unlimited due to the comment tag 'X'.
  char h[1024];
  RTC_CHECK(fgets(h, sizeof(h), file) != NULL)
      << "File " << filepath << " is too small";
  fclose(file);

  RTC_CHECK(sscanf(h, "YUV4MPEG2 W%d H%d", &resolution->width,
                   &resolution->height) == 2)
      << filepath << " is not a valid Y4M file";

  RTC_CHECK_GT(resolution->width, 0) << "Width must be positive";
  RTC_CHECK_GT(resolution->height, 0) << "Height must be positive";

  *header_size = strcspn(h, "\n") + 1;
  RTC_CHECK(static_cast<unsigned>(*header_size) < sizeof(h))
      << filepath << " has unexpectedly large header";
}

Y4mFrameReaderImpl::Y4mFrameReaderImpl(std::string filepath,
                                       RepeatMode repeat_mode)
    : YuvFrameReaderImpl(filepath, Resolution(), repeat_mode) {}

void Y4mFrameReaderImpl::Init() {
  file_ = fopen(filepath_.c_str(), "rb");
  RTC_CHECK(file_ != nullptr) << "Cannot open " << filepath_;

  ParseY4mHeader(filepath_, &resolution_, &header_size_bytes_);
  frame_size_bytes_ =
      CalcBufferSize(VideoType::kI420, resolution_.width, resolution_.height);
  frame_size_bytes_ += kFrameHeaderSize;

  size_t file_size_bytes = GetFileSize(filepath_);
  RTC_CHECK_GT(file_size_bytes, 0u) << "File " << filepath_ << " is empty";
  RTC_CHECK_GT(file_size_bytes, header_size_bytes_)
      << "File " << filepath_ << " is too small";

  num_frames_ = static_cast<int>((file_size_bytes - header_size_bytes_) /
                                 frame_size_bytes_);
  RTC_CHECK_GT(num_frames_, 0u) << "File " << filepath_ << " is too small";
  header_size_bytes_ += kFrameHeaderSize;
}

std::unique_ptr<FrameReader> CreateY4mFrameReader(std::string filepath) {
  return CreateY4mFrameReader(filepath,
                              YuvFrameReaderImpl::RepeatMode::kSingle);
}

std::unique_ptr<FrameReader> CreateY4mFrameReader(
    std::string filepath,
    YuvFrameReaderImpl::RepeatMode repeat_mode) {
  Y4mFrameReaderImpl* frame_reader =
      new Y4mFrameReaderImpl(filepath, repeat_mode);
  frame_reader->Init();
  return std::unique_ptr<FrameReader>(frame_reader);
}

}  // namespace test
}  // namespace webrtc
