#ifndef __SERVER__GRPC__STREAM__HH_H_
#define __SERVER__GRPC__STREAM__HH_H_
#include "opencv2/opencv.hpp"
#include <pcl/point_cloud.h>
#include <pcl/point_types.h>
#include <thread>
#include <grpcpp/grpcpp.h>
#include "def.grpc.grpc.pb.h"
#include "def.grpc.pb.h"

class CustomServer :public JetStream::StreamServer::Service
{
private:
    
    bool openDataStream_=false;
    bool openImageStream_=false;
    ::JetStream::ResFrame frame_;
    bool update_;
public:
    CustomServer();
    ~CustomServer();
    void update(const ::JetStream::ResFrame& frame);
    ::grpc::Status OpenImageStream(::grpc::ServerContext* context, 
            const ::JetStream::RequestCmd* request, ::grpc::ServerWriter< ::JetStream::ResImage>* writer);
    virtual ::grpc::Status OpenMeasureDataStream(::grpc::ServerContext* context, const ::JetStream::RequestCmd* request, 
            ::grpc::ServerWriter< ::JetStream::MeasureInfo>* writer);
    virtual ::grpc::Status Detect(::grpc::ServerContext* context, 
            const ::JetStream::RequestCmd* request, ::JetStream::ResFrame* response);
    virtual ::grpc::Status CloseImageStream(::grpc::ServerContext* context, const ::JetStream::RequestCmd* request, 
            ::JetStream::Response* response);
    virtual ::grpc::Status CloseMeasureDataStream(::grpc::ServerContext* context, const ::JetStream::RequestCmd* request, 
            ::JetStream::Response* response);
    virtual ::grpc::Status GetCloud(::grpc::ServerContext* context, const ::JetStream::RequestCmd* request, 
            ::JetStream::ResCloud* response);
    virtual ::grpc::Status GetImage(::grpc::ServerContext* context, const ::JetStream::RequestCmd* request, 
            ::JetStream::ResImage* response);

protected:
    bool waitForUpdata(float tm);
};


class StreamRpcServer{

private:
    grpc::ServerBuilder builder_;
    CustomServer service_;
    std::unique_ptr<grpc::Server> server_;
    std::thread* thread_;
    
public:
    StreamRpcServer();
    ~StreamRpcServer();
    void Listenning(std::string ip,int port);
    void ResetData(const ::JetStream::ResFrame& frame);

    static ::JetStream::Image cvMat2JetImage(cv::Mat& image);
    static ::JetStream::PointCloud pcl2JetPointCloud(pcl::PointCloud<pcl::PointXYZI>::Ptr pcl);
    static ::JetStream::PointCloud cvPointMat2JetPointCloud(cv::Mat& image);

protected:
    static void WaitThread(void* p);
};

#endif