#ifndef ANSGSTREAMER_H
#define ANSGSTREAMER_H
#define ANSGS_API __declspec(dllexport)

#include <iostream>
#include <tuple>
#include <gst/gst.h>
#include <gst/app/gstappsink.h>
#include <opencv2/opencv.hpp>
#include "LabVIEWHeader/extcode.h"
#include "ANSLicense.h"

namespace ANSCENTER {
    class ANSGS_API ANSGStreamerReader
    {
    public:
        bool Init(std::string licenseKey,std::string URL);
        void Destroy();
        bool GetImageInfo(int& imageWidth, int& imageHeight, int &status, std::string& timeStamp);
        cv::Mat GetImage();
        static std::string MatToBinaryData(const cv::Mat& image);
        static cv::Mat JpegStringToMat(const std::string& jpegStr);
        bool Start();
        bool Stop();
        void Run();

        //void HandleNetworkLoss();

    protected:
      /*  static gboolean OnNetworkLoss(gpointer user_data) {
            ANSGStreamerReader* player = static_cast<ANSGStreamerReader*>(user_data);
            player->HandleNetworkLoss();
            return TRUE;
        }*/
        static gboolean OnMessage(GstBus* bus, GstMessage* message, gpointer user_data) {
            ANSGStreamerReader* player = static_cast<ANSGStreamerReader*>(user_data);
            switch (GST_MESSAGE_TYPE(message)) {
            case GST_MESSAGE_ERROR:
                gchar* debug;
                GError* error;
                gst_message_parse_error(message, &error, &debug);
                g_printerr("Error received: %s\n", error->message);
                g_error_free(error);
                g_free(debug);
                break;
            case GST_MESSAGE_ELEMENT:
                // Handle any specific element messages here
                break;
            default:
                break;
            }
            return TRUE;
        }
    private:


        SPDLogger* _logger = SPDLogger::GetInstance("ANSGSLog", false);
        void CheckLicense();
        bool CreatePipeline(std::string pipeline);
        std::tuple<int, int, unsigned char*> ProcessSamples();
        void UnRefSample();
        GstElement* gst_pipeline;
        GstBus* gst_bus;
        GstElement* cvdsink;
        GstSample* sample = NULL;
        GstBuffer* buffer = NULL;
        GstCaps* caps = NULL;
        GstClockTime buffer_ts;
        GstMapInfo map = { 0 };
        guint       timer_id;           // Timer ID for network monitoring
        std::string timeStr{};

        guint64 lastDataTimestamp;     // Timestamp of last data reception
        guint64 currentDataTimestamp;     // Timestamp of last data reception

        gboolean dataLossDetected;      // Flag to indicate data loss
        guint64 dataLossThreshold;     // Threshold for data loss detection (in nanoseconds)

        bool            _licenseValid{ false };
        std::string     _licenseKey{};
        int width;
        int height;
    };
}

extern "C" __declspec(dllexport) int CreateANSGSHandle(ANSCENTER::ANSGStreamerReader * *Handle, const char* licenseKey,const char* URL);
extern "C" __declspec(dllexport) int ReleaseANSGSHandle(ANSCENTER::ANSGStreamerReader * *Handle);
extern "C" __declspec(dllexport) std::string GetImage(ANSCENTER::ANSGStreamerReader * *Handle);
extern "C" __declspec(dllexport) int GetImage_LV(ANSCENTER::ANSGStreamerReader * *Handle, LStrHandle detectionResult);
extern "C" __declspec(dllexport) int GetImageInformation(ANSCENTER::ANSGStreamerReader **Handle, int* iWidth, int* iHeight, int* status, LStrHandle timeStamp);
extern "C" __declspec(dllexport) int Start(ANSCENTER::ANSGStreamerReader * *Handle);
extern "C" __declspec(dllexport) int Stop(ANSCENTER::ANSGStreamerReader * *Handle);

#endif // GSTREAMER_READER_H