#include <vector>
#include <string.h>
#include <fstream>
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/imgcodecs.hpp>
#include <opencv2/imgproc.hpp>

using namespace cv;
using namespace std;
namespace fs = std::__fs::filesystem;
using json = nlohmann::json;

void extractIrregularityImagesForAudio(std::string outputPath, std::string videoPath, json irregularityFileInput, json &irregularityFileOutput2) {

	// Make fromAudioAnalyser folder
	int capsDirectory = fs::create_directory(outputPath + "fromAudioAnalyser/");

	// Open video
	cv::VideoCapture videoCapture(videoPath);

	// Compute video length in milliseconds
	int frameCount = videoCapture.get(CAP_PROP_FRAME_COUNT);
	int fps = videoCapture.get(CAP_PROP_FPS);
	int videoLenghtMS = (frameCount / fps) * 1000 + std::round((float)((frameCount % fps) * 1000) / fps);

	for (int i = 0; i < irregularityFileInput["Irregularities"].size(); i++) {
		// Declare output image frame
		cv::Mat frame;
		std::string framePath;
		// Extract TimeLabel from input JSON
		std::string timeLabel = irregularityFileInput["Irregularities"][i]["TimeLabel"];
		// Obtain time measures from JSON
		int h = stoi(timeLabel.substr(0, 2));
		int min = stoi(timeLabel.substr(3, 2));
		int sec = stoi(timeLabel.substr(6, 2));
		int ms = stoi(timeLabel.substr(9, 3));

		std::string safeTimeLabel = timeLabel;
		safeTimeLabel[2] = '-';
		safeTimeLabel[5] = '-';
		safeTimeLabel[8] = '-';

		// Compute the Irregularity instant in milliseconds
		int irrInstMS = ms + sec*1000 + min*60000 + h*3600000;
		// Compute the frame number corresponding to the Irregularity
		int irrFrame = std::round((float)(irrInstMS/1000)*fps);

		try {
			framePath = outputPath + "fromAudioAnalyser/AudioIrregularity_" + safeTimeLabel + ".jpg";
			videoCapture.set(CAP_PROP_POS_FRAMES, irrFrame);
			videoCapture >> frame;
			cv::imwrite(framePath, frame);

			// Append Irregularity information to JSON
			boost::uuids::uuid uuid = boost::uuids::random_generator()();
			irregularityFileOutput2["Irregularities"] += {{
					"IrregularityID", irregularityFileInput["Irregularities"][i]["IrregularityID"]
				}, {
					"Source", "a"
				}, {
					"TimeLabel", timeLabel
				}, {
					"ImageURI", framePath
				}
			};
		} catch (cv::Exception e) {
			std::cout << "\033[0;31mTimeLabel error for Audio Analyser Irregularity " << i << "." << std::endl;
		}
	}
}