#include "core/project_model.hpp"
#include "core/json.hpp"
#include <sstream>
#include <unordered_set>
namespace smartcut::core {
namespace { std::string portable_path(std::string value) { for (auto& character : value) if (character == '\\') character = '/'; return value; } }
bool Project::valid() const {
  std::unordered_set<std::string> source_ids;
  for (const auto& source : sources_) if (!source.source_uuid.empty() && source_ids.insert(source.source_uuid).second == false) return false;
  for (const auto& segment : segments_) if (segment.source_uuid.empty() || source_ids.find(segment.source_uuid) == source_ids.end() || segment.end_display_frame_exclusive <= segment.first_display_frame) return false;
  return true;
}
std::string Project::to_json() const {
  std::ostringstream output; output << "{\"schema\":\"project-v1\",\"sources\":[";
  for (std::size_t i = 0; i < sources_.size(); ++i) { if (i) output << ','; const auto& source = sources_[i]; output << "{\"source_uuid\":\"" << json_escape(source.source_uuid) << "\",\"canonical_path\":\"" << json_escape(portable_path(source.canonical_path)) << "\",\"audio_stream\":" << source.audio_stream << ",\"audio_time_base_num\":" << source.audio_time_base_num << ",\"audio_time_base_den\":" << source.audio_time_base_den << ",\"audio_sample_rate\":" << source.audio_sample_rate << ",\"audio_channels\":" << source.audio_channels << ",\"selected_streams\":["; for (std::size_t stream = 0; stream < source.selected_streams.size(); ++stream) { if (stream) output << ','; output << source.selected_streams[stream]; } output << "]}"; }
  output << "],\"segments\":[";
  for (std::size_t i = 0; i < segments_.size(); ++i) { if (i) output << ','; const auto& segment = segments_[i]; output << "{\"source_uuid\":\"" << json_escape(segment.source_uuid) << "\",\"video_stream\":" << segment.video_stream << ",\"first_display_frame\":" << segment.first_display_frame << ",\"end_display_frame_exclusive\":" << segment.end_display_frame_exclusive << '}'; }
  output << "],\"exports\":["; for (std::size_t i = 0; i < exports_.size(); ++i) { if (i) output << ','; const auto& evidence = exports_[i]; output << "{\"source_uuid\":\"" << json_escape(evidence.source_uuid) << "\",\"output_uuid\":\"" << json_escape(evidence.output_uuid) << "\",\"first_frame\":" << evidence.first_frame << ",\"end_frame\":" << evidence.end_frame << ",\"status\":\"" << json_escape(evidence.status) << "\"}"; } output << "],\"chapter_markers\":["; for (std::size_t marker = 0; marker < chapter_markers_.size(); ++marker) { if (marker) output << ','; output << chapter_markers_[marker]; } output << "],\"scene_mode\":" << (scene_mode_ ? "true" : "false") << ",\"audio_offset_ms\":" << audio_offset_ms_ << ",\"journal_path\":\"" << json_escape(portable_path(journal_path_)) << "\",\"audio_validation_status\":\"" << json_escape(audio_validation_status_) << "\"}"; return output.str();
}
}  // namespace smartcut::core
