void fill_message(const std::shared_ptr<FrameObject>& fo,
                  FrameObjectMsg* msg) {
  CHECK_NOTNULL(msg);
  msg->set_uuid(rslam::uuid::uuid_begin(fo->id),
                rslam::uuid::uuid_size(fo->id));

  switch (fo->type) {
    case FrameObject::Type::Cube:
      msg->set_type(FrameObjectMsg::Cube);
      fill_message(std::static_pointer_cast<CubeObject>(fo),
                   msg->MutableExtension(CubeObjectMsg::object));
      break;
    case FrameObject::Type::Teapot:
      msg->set_type(FrameObjectMsg::Teapot);
      fill_message(std::static_pointer_cast<TeapotObject>(fo),
                   msg->MutableExtension(TeapotObjectMsg::object));
      break;
    case FrameObject::Type::Text:
      msg->set_type(FrameObjectMsg::Text);
      fill_message(std::static_pointer_cast<TextObject>(fo),
                   msg->MutableExtension(TextObjectMsg::object));
      break;
    default:
      LOG(FATAL) << "Unkown FrameObject type being serialized";
  }
}
void fill_message(const std::shared_ptr<TextObject>& fo,
                  TextObjectMsg* msg) {
  CHECK_NOTNULL(msg);

  WritePoseSE3(fo->t_po, msg->mutable_t_po());
  fill_message(fo->scale, msg->mutable_scale());
  msg->set_text(fo->text);
  fill_message(fo->color, msg->mutable_color());
}
void run_main_loop(SOCKET *socket_server)
{
    broadcast_message_t previous_message = { 0 };
    char buffer[BUFFER_LENGTH] = { 0 };

    while (1)
    {
        broadcast_message_t message = { 0 };
        if (fill_message(socket_server, &message, &buffer) < 0) {
            break;
        }
        if (parse_msg_json(buffer, strlen(buffer), &message) != 0) {
            fprintf(stderr, "Fail parse json\n");
        }
        else {
            if (!are_same_messages(&previous_message, &message))
            {
                /*
                print_message(&previous_message);
                print_message(&message);
                */
                interpret_message(&message);
            }
        }
        previous_message = message;
    }
}
void fill_message(const std::shared_ptr<CubeObject>& fo,
                  CubeObjectMsg* msg) {
  CHECK_NOTNULL(msg);

  WritePoseSE3(fo->t_po, msg->mutable_t_po());
  fill_message(fo->scale, msg->mutable_scale());
}
//size_t handleChunk(char* nid,char* csn,long tag,size_t left_edge, size_t segment_size,void* buffer)
size_t handleChunk(char* nid,unsigned long long csn,long tag,unsigned long long chunk_size,void* buffer)
{
	size_t writtenBytes,fileNameSize;
	char* fileName;
	char csnToDelete[64];
	FILE *fp;
	UT_string* folderName;
	utstring_new(folderName);
	UT_string* tempHexCsn;
	utstring_new(tempHexCsn);
	UT_string* filename; utstring_new(filename);


	//variables for cache table
	CacheEntry_t 	*entry, *tmp_entry; 
	CacheEntry_t	*entryToDelete=NULL;
	UT_string 		*utnid, *filenameToDelete;
	//	long 			csnlong;

	//folderName=NULL;
	if(CONET_DEBUG) fprintf(stderr,"\n[cacheEngine.c:%d]New segment nid=%s, csn=%llu received.\n",
		__LINE__,nid,csn);

	calculate_filename(nid,csn,filename);

	utstring_printf(folderName,CONTAINING_FOLDER);
	utstring_printf(folderName,nid);
	mkdir(utstring_body(folderName));
	fp = fopen(utstring_body(filename) , "w+b");

	if (fp == NULL) {
		fprintf(stderr, "Error: Failed to open the file %s for writing;\n\n", fileName);
		if (CONET_SEVERE_DEBUG) exit(-863);
		return ( (size_t) - 1);
	}

	writtenBytes = fwrite(buffer, 1,chunk_size, fp);
	fclose(fp);

	if (writtenBytes!=chunk_size) {
		fprintf(stderr, "Error in writing %s: writtenBytes=%d, while chunk_size=%d\n",
				fileName,writtenBytes,chunk_size);
		if (CONET_SEVERE_DEBUG) exit(-8763);
		return ( (size_t) - 1);
	}

	utstring_new(utnid); utstring_printf(utnid,nid);
	//utstring_printf(tempHexCsn,"0x");utstring_printf(tempHexCsn,csn);
	ADD_TO_CACHE_TABLE(cache_table,entry,tmp_entry,tag,utnid,csn,chunk_size,0,entryToDelete);
	
	//creates json message with nid and of type "stored", and store it to msg_to_controller_buffer;
	fill_message(tag, "stored", nid, csn, msg_to_controller_buffer);
	//BUFFERLEN is defined in c_json.h
	int bytesSentToController=send(socket_to_controller, msg_to_controller_buffer, BUFFERLEN, 0);
	if(CONET_DEBUG )
		fprintf(stderr,"[cacheEngine.c:%d]Message sent to controller = %s\n",__LINE__,msg_to_controller_buffer);
	if 	(bytesSentToController <=strlen(msg_to_controller_buffer) )
	{
        fprintf(stderr,"[cacheEngine.c: %d] bytes sent to controller=%d\n",__LINE__, bytesSentToController);
        if (CONET_SEVERE_DEBUG) exit(-982);
    }



	if (entryToDelete!=NULL)
	{
		sprintf(csnToDelete,"%x",(unsigned int) entryToDelete->csn);
		CALCULATE_UTSTRING_FILE_NAME(entryToDelete->nid,csnToDelete,filenameToDelete);

		if (remove(utstring_body(filenameToDelete) )==0)
			fprintf(stderr,"File %s deleted.\n",utstring_body(filenameToDelete));
		else
			fprintf(stderr,"Error deleting file %s,\n",utstring_body(filenameToDelete));

		//creates json message with nid and of type "stored", and store it to msg_to_controller_buffer;
		fill_message(entryToDelete->tag, "deleted", entryToDelete->nid, entryToDelete->csn, msg_to_controller_buffer);
		//BUFFERLEN is defined in c_json.h
		if 	(send(socket_to_controller, msg_to_controller_buffer, BUFFERLEN, 0) != 
				strlen(msg_to_controller_buffer)
			)
		    fprintf(stderr,"send() sent a different number of bytes than expected\n");
		
		
	}

	fprintf(stderr,"[cacheEngine.c:%d]New chunk added: nid=%s, csn=%llu, tag=%ld\n",__LINE__,nid,csn,tag);

	//    utstring_free(utnid); utstring_free(filenameToDelete);
	utstring_free(filename);

	return writtenBytes;
}