#pragma once

#include <cstddef>
#include <string>
#include <utility>
#include <vector>

namespace smartcut::media {
struct MkvBoundaryAnalysis {
  std::vector<std::size_t> random_access_frames;
  // MPEG-2 open GOPs can place display-order B pictures immediately before
  // their following I picture.  A tail replacement must begin at the first of
  // those B pictures, not at the I picture, or the copied prefix retains
  // pictures whose forward reference was removed.
  std::vector<std::pair<std::size_t, std::size_t>> mpeg2_tail_encode_starts;
  // Open GOPs in MPEG-2, H.264, and HEVC can place pictures immediately
  // before a random-access picture in display order while decoding them after
  // it. A tail replacement must include those leading pictures.
  std::vector<std::pair<std::size_t, std::size_t>> dependency_tail_encode_starts;
  bool mpeg2_video{};
  bool mpeg2_end_dependency_complete{};
};

MkvBoundaryAnalysis analyze_mkv_boundaries(const std::string& input,
                                           std::size_t first_video_frame,
                                           std::size_t end_video_frame);
std::vector<std::size_t> mkv_random_access_frames(const std::string& input,
                                                  std::size_t first_video_frame,
                                                  std::size_t end_video_frame);
std::string copy_mkv_timed_range(const std::string& input, const std::string& output,
                                 std::size_t first_video_packet, std::size_t end_video_packet);
std::string validate_mkv_timed_range(const std::string& input, const std::string& output,
                                     std::size_t first_video_packet, std::size_t end_video_packet);
std::string mux_mkv_boundary_timed_range(const std::string& input, const std::string& boundary_video,
                                         const std::string& output, std::size_t first_video_frame,
                                         std::size_t end_video_frame);
std::string validate_mkv_boundary_timed_range(const std::string& input, const std::string& boundary_video,
                                              const std::string& output, std::size_t first_video_frame,
                                              std::size_t end_video_frame);
}
