/*
 *  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 "modules/video_coding/utility/ivf_file_reader.h"

#include <cstddef>
#include <cstdint>
#include <cstring>
#include <memory>
#include <optional>
#include <string>

#include "api/scoped_refptr.h"
#include "api/video/encoded_image.h"
#include "api/video/video_codec_type.h"
#include "modules/video_coding/utility/ivf_file_writer.h"
#include "rtc_base/system/file_wrapper.h"
#include "test/gtest.h"
#include "test/testsupport/file_utils.h"

namespace webrtc {
namespace {

constexpr int kWidth = 320;
constexpr int kHeight = 240;
constexpr int kNumFrames = 3;
constexpr uint8_t kDummyPayload[4] = {'0', '1', '2', '3'};

}  // namespace

class IvfFileReaderTest : public ::testing::Test {
 protected:
  void SetUp() override {
    file_name_ = test::TempFilename(test::OutputPath(), "test_file.ivf");
  }
  void TearDown() override { test::RemoveFile(file_name_); }

  bool WriteDummyTestFrames(IvfFileWriter* file_writer,
                            VideoCodecType codec_type,
                            int width,
                            int height,
                            int num_frames,
                            bool use_capture_tims_ms,
                            int spatial_layers_count) {
    EncodedImage frame;
    frame.SetSpatialIndex(spatial_layers_count);
    scoped_refptr<EncodedImageBuffer> payload = EncodedImageBuffer::Create(
        sizeof(kDummyPayload) * spatial_layers_count);
    for (int i = 0; i < spatial_layers_count; ++i) {
      memcpy(&payload->data()[i * sizeof(kDummyPayload)], kDummyPayload,
             sizeof(kDummyPayload));
      frame.SetSpatialLayerFrameSize(i, sizeof(kDummyPayload));
    }
    frame.SetEncodedData(payload);
    frame._encodedWidth = width;
    frame._encodedHeight = height;
    for (int i = 1; i <= num_frames; ++i) {
      if (use_capture_tims_ms) {
        frame.capture_time_ms_ = i;
      } else {
        frame.SetRtpTimestamp(i);
      }
      if (!file_writer->WriteFrame(frame, codec_type))
        return false;
    }
    return true;
  }

  void CreateTestFile(VideoCodecType codec_type,
                      bool use_capture_tims_ms,
                      int spatial_layers_count) {
    std::unique_ptr<IvfFileWriter> file_writer =
        IvfFileWriter::Wrap(file_name_, /*byte_limit=*/0);
    ASSERT_TRUE(file_writer.get());
    ASSERT_TRUE(WriteDummyTestFrames(file_writer.get(), codec_type, kWidth,
                                     kHeight, kNumFrames, use_capture_tims_ms,
                                     spatial_layers_count));
    ASSERT_TRUE(file_writer->Close());
  }

  void ValidateFrame(std::optional<EncodedImage> frame,
                     int frame_index,
                     bool use_capture_tims_ms,
                     int spatial_layers_count) {
    ASSERT_TRUE(frame);
    EXPECT_EQ(frame->SpatialIndex(), spatial_layers_count - 1);
    if (use_capture_tims_ms) {
      EXPECT_EQ(frame->capture_time_ms_, static_cast<int64_t>(frame_index));
      EXPECT_EQ(frame->RtpTimestamp(), static_cast<int64_t>(90 * frame_index));
    } else {
      EXPECT_EQ(frame->RtpTimestamp(), static_cast<int64_t>(frame_index));
    }
    ASSERT_EQ(frame->size(), sizeof(kDummyPayload) * spatial_layers_count);
    for (int i = 0; i < spatial_layers_count; ++i) {
      EXPECT_EQ(memcmp(&frame->data()[i * sizeof(kDummyPayload)], kDummyPayload,
                       sizeof(kDummyPayload)),
                0)
          << std::string(reinterpret_cast<char const*>(
                             &frame->data()[i * sizeof(kDummyPayload)]),
                         sizeof(kDummyPayload));
    }
  }

  void ValidateContent(VideoCodecType codec_type,
                       bool use_capture_tims_ms,
                       int spatial_layers_count) {
    std::unique_ptr<IvfFileReader> reader =
        IvfFileReader::Create(FileWrapper::OpenReadOnly(file_name_));
    ASSERT_TRUE(reader.get());
    EXPECT_EQ(reader->GetVideoCodecType(), codec_type);
    EXPECT_EQ(reader->GetFramesCount(),
              spatial_layers_count * static_cast<size_t>(kNumFrames));
    for (int i = 1; i <= kNumFrames; ++i) {
      ASSERT_TRUE(reader->HasMoreFrames());
      ValidateFrame(reader->NextFrame(), i, use_capture_tims_ms,
                    spatial_layers_count);
      EXPECT_FALSE(reader->HasError());
    }
    EXPECT_FALSE(reader->HasMoreFrames());
    EXPECT_FALSE(reader->NextFrame());
    EXPECT_FALSE(reader->HasError());
    ASSERT_TRUE(reader->Close());
  }

  std::string file_name_;
};

TEST_F(IvfFileReaderTest, BasicVp8FileNtpTimestamp) {
  CreateTestFile(kVideoCodecVP8, false, 1);
  ValidateContent(kVideoCodecVP8, false, 1);
}

TEST_F(IvfFileReaderTest, BasicVP8FileMsTimestamp) {
  CreateTestFile(kVideoCodecVP8, true, 1);
  ValidateContent(kVideoCodecVP8, true, 1);
}

TEST_F(IvfFileReaderTest, BasicVP9FileNtpTimestamp) {
  CreateTestFile(kVideoCodecVP9, false, 1);
  ValidateContent(kVideoCodecVP9, false, 1);
}

TEST_F(IvfFileReaderTest, BasicVP9FileMsTimestamp) {
  CreateTestFile(kVideoCodecVP9, true, 1);
  ValidateContent(kVideoCodecVP9, true, 1);
}

TEST_F(IvfFileReaderTest, BasicAv1FileNtpTimestamp) {
  CreateTestFile(kVideoCodecAV1, false, 1);
  ValidateContent(kVideoCodecAV1, false, 1);
}

TEST_F(IvfFileReaderTest, BasicAv1FileMsTimestamp) {
  CreateTestFile(kVideoCodecAV1, true, 1);
  ValidateContent(kVideoCodecAV1, true, 1);
}

TEST_F(IvfFileReaderTest, BasicH264FileNtpTimestamp) {
  CreateTestFile(kVideoCodecH264, false, 1);
  ValidateContent(kVideoCodecH264, false, 1);
}

TEST_F(IvfFileReaderTest, BasicH264FileMsTimestamp) {
  CreateTestFile(kVideoCodecH264, true, 1);
  ValidateContent(kVideoCodecH264, true, 1);
}

TEST_F(IvfFileReaderTest, MultilayerVp8FileNtpTimestamp) {
  CreateTestFile(kVideoCodecVP8, false, 3);
  ValidateContent(kVideoCodecVP8, false, 3);
}

TEST_F(IvfFileReaderTest, MultilayerVP9FileNtpTimestamp) {
  CreateTestFile(kVideoCodecVP9, false, 3);
  ValidateContent(kVideoCodecVP9, false, 3);
}

TEST_F(IvfFileReaderTest, MultilayerAv1FileNtpTimestamp) {
  CreateTestFile(kVideoCodecAV1, false, 3);
  ValidateContent(kVideoCodecAV1, false, 3);
}

TEST_F(IvfFileReaderTest, MultilayerH264FileNtpTimestamp) {
  CreateTestFile(kVideoCodecH264, false, 3);
  ValidateContent(kVideoCodecH264, false, 3);
}

}  // namespace webrtc
