#pragma once

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

namespace smartcut::media {

enum class OutputContainer { matroska, mp4, mov, mpeg_ps, mpeg_ts, wtv, dvr_ms, topfield_rec, mxf, elementary, unsupported };

struct MpegTsMuxOptions {
  int transport_stream_id = 1;
  int original_network_id = 0xff01;
  int service_id = 1;
  int pmt_start_pid = 0x1000;
  int elementary_start_pid = 0x0100;
  int mux_rate = 0;
  int pcr_period_ms = -1;
  double pat_period_seconds = 0.1;
  double sdt_period_seconds = 0.5;
  bool m2ts_mode = false;
  bool resend_headers = true;
  bool system_b = false;
  bool emit_nit = false;
  std::string service_name{"SmartCut64"};
  std::string service_provider{"SmartCut64"};
};

using ContainerMetadata = std::vector<std::pair<std::string, std::string>>;

OutputContainer output_container_for_path(const std::string& path);
const char* output_container_name(OutputContainer container);

// Packet-copy an already rendered, zero-based intermediate into the requested
// delivery container and validate the result. No elementary stream is encoded.
std::string remux_media_container(const std::string& input, const std::string& output,
                                  const MpegTsMuxOptions& transport_stream = {},
                                  const ContainerMetadata& metadata = {});

// Multiplex independent elementary-stream or single-stream container inputs
// into one delivery container without decoding their payloads. Inputs are
// interleaved by timestamp and the completed file is reopened and validated.
std::string multiplex_elementary_streams(const std::vector<std::string>& inputs,
                                         const std::string& output,
                                         const MpegTsMuxOptions& transport_stream = {});

// Split a rendered source into one packet-copied file per audio/video stream.
// The first video stream uses `output`; sibling streams receive codec-specific
// extensions next to it. Outputs are validated and promoted as one operation.
std::string demultiplex_elementary_streams(const std::string& input,
                                           const std::string& output);

// Container-aware complete-source and selected-stream exports. Matroska keeps
// the lossless audit used by the native pipeline; other formats are first
// rendered to a validated Matroska intermediate and then packet-remuxed.
std::string export_media(const std::string& input, const std::string& output,
                         const MpegTsMuxOptions& transport_stream = {});
std::string export_media_selected_streams(const std::string& input, const std::string& output,
                                          const std::vector<std::size_t>& streams,
                                          const MpegTsMuxOptions& transport_stream = {});

}  // namespace smartcut::media
