/*
   Author: David Spisla
*/
#include <ctype.h>
#include <sys/uio.h>

#include "glusterfs.h"
#include "xlator.h"
#include "logging.h"
#include "stub-mem-types.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
/*
 * This is a test xlator to write and read a stub-file
 * and extract informations about the path to
 * the original file. This is just for testing
 * issue, not for production use.
 */



int32_t
stub_readv_cbk (call_frame_t *frame,
                 void *cookie,
                 xlator_t *this,
                 int32_t op_ret,
                 int32_t op_errno,
                 struct iovec *vector,
                 int32_t count,
		 struct iatt *stbuf,
                 struct iobref *iobref, dict_t *xdata)
{       
        
        struct iovec *new_vec;
        struct iobref *new_iobref;
        iobref_clear (iobref);
        char temp[] = "I am the new content!!!\n";
        char *buf0 = "I am the new content!!!\n";              
                
        stbuf->ia_size = sizeof(temp);

        new_vec = GF_CALLOC(1, sizeof(temp), gf_stub_mt_iovec);
       
        struct iobuf *iobuf = NULL;
	    iobuf = iobuf_get2(this->ctx->iobuf_pool, sizeof(temp));
        iobuf->ptr = buf0;
        iobuf->free_ptr = buf0;
        new_iobref = iobref_new();
        iobref_add(new_iobref, iobuf);
        
        new_vec[0].iov_base = buf0;
        new_vec[0].iov_len = sizeof(temp);
        
         
	STACK_UNWIND_STRICT (readv, frame, stbuf->ia_size, op_errno, new_vec, count,
                             stbuf, new_iobref, xdata);
	return 0;
}


int32_t
stub_readv (
	call_frame_t *frame,
	xlator_t *this,
	fd_t * fd,
	size_t size,
	off_t offset,
	uint32_t flags,
	dict_t * xdata)
{       


	STACK_WIND (frame,
                    stub_readv_cbk,
	                FIRST_CHILD(this),
                    FIRST_CHILD(this)->fops->readv,
	            fd, size, offset, flags, xdata);
	return 0;
}


int32_t
stub_writev (
	call_frame_t *frame,
	xlator_t *this,
	fd_t * fd,
	struct iovec * vector,
	int32_t count,
	off_t off,
	uint32_t flags,
	struct iobref * iobref,
	dict_t * xdata)
{ 

	STACK_WIND_TAIL (frame,
			 FIRST_CHILD(this), FIRST_CHILD(this)->fops->writev,
			 fd, vector, count, off, flags, iobref, xdata);
	return 0;
}

int32_t
stub_lookup_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
		    int32_t op_ret, int32_t op_errno, inode_t * inode,
	struct iatt * buf,
	dict_t * xdata,
	struct iatt * postparent)
{

        STACK_UNWIND_STRICT (lookup, frame, op_ret, op_errno,
			     inode, buf, xdata, postparent);
	return 0;
}

int32_t
stub_lookup (
	call_frame_t *frame,
	xlator_t *this,
	loc_t * loc,
	dict_t * xdata)
{       
        
	STACK_WIND (frame, stub_lookup_cbk,
			 FIRST_CHILD(this), FIRST_CHILD(this)->fops->lookup,
			 loc, xdata);
	return 0;
}



int32_t
init (xlator_t *this)
{
	data_t *data = NULL;

	if (!this->parents) {
		gf_log (this->name, GF_LOG_WARNING,
			"dangling volume. check volfile ");
	}

	gf_log ("stub", GF_LOG_DEBUG, "stub xlator loaded");
	return 0;
}

void
fini (xlator_t *this)
{
        this->private = NULL;
	return;
}

struct xlator_fops fops = {
	.readv        = stub_readv,
        .writev       = stub_writev,
        .lookup       = stub_lookup
};

struct xlator_cbks cbks;

struct volume_options options[] = {
};

