#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 "proto/def.grpc.grpc.pb.h"
#include "proto/def.grpc.pb.h"
#include "vzense/tof3d_transformation.hpp"

class CustomServer : public JetStream::StreamServer::Service {
private:

    bool openDataStream_ = false;
    bool openImageStream_ = false;
    bool update_;
public:
    CustomServer();

    ~CustomServer();

    ::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 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);

    virtual ::grpc::Status setTofTransformation(::grpc::ServerContext *context, const ::JetStream::RequestCmd *request,
                                              ::JetStream::Response *response);
                                              
    virtual ::grpc::Status saveTofTransformation(::grpc::ServerContext *context, const ::JetStream::RequestCmd *request,
                                              ::JetStream::Response *response);
protected:
    static ::JetStream::Image cvMat2JetImage(cv::Mat &image);
};


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);


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

#endif
