//
//p-nodet.c
//
//A pipe which transfers noderefs. Will probably be eventually removed.
//
//
//-UserX 2001/12/06

#include <stdlib.h>
#include <string.h>
//#include <stdio.h>

#include "base/dblock.h"
#include "base/mem.h"
#include "base/str.h"
#include "pipe/nodetran.h"
#include "base/logger.h"

#include "net/nodeserv.h"

#include "file/file.h"

PipeNodeTrans blankpipenodetrans = BLANKPIPENODETRANS;

int nodetransget = 0;
int nodetranssend = 0;
char *nodetransfile = "";

Pipe *pipenodetransMake(char *pipename, char *options) {
	PipeNodeTrans *thispipe = memCopy(&blankpipenodetrans, sizeof(PipeNodeTrans), "PipeNodeTrans", NULL);
	pipeInitFunctions((Pipe *) thispipe, 
			(PipeFuncIn) pipenodetransRead, (PipeFuncOut) pipenodetransWrite, 
			(PipeFuncAttach) pipenodetransAttach, (PipeFuncDetach) pipenodetransDetach, 
			(PipeFuncClose) pipenodetransClose, (PipeFuncStatus) pipenodetransStatus);
	pipeInit((Pipe *) thispipe);
	return (Pipe *)thispipe;
}

void pipenodetransFree(PipeNodeTrans *thispipe) {
	pipeFree(&thispipe->IOPipe);
	memFree(thispipe);
}

void pipenodetransRead(PipeNodeTrans *thispipe, Pipe **errPipe) {
	FileHandle *fh;
	char *s;
	*errPipe = pipeGenericRead(thispipe->IOPipe.backPipe);
	if(*errPipe == NULL) {
		if(thispipe->inhandshake == 1) {
			s = dblockGetString(thispipe->IOPipe.backPipe->inBuffer);
			if(s != NULL) {
				LOGDEBUG(stringCopyMany("nodeget:\n", s, "-end-", NULL));
				if(nodetransget != 0 && !isStringBlank(s) && nodeservNodeRefListValid(s)) {
					//todo: error checkking/logging
					fh = fileOpen(nodereffilename, "w");
					if(fh != NULL) {
						fileWriteStringKeep(fh, s);
						fileClose(fh);
					}
					nodeservClearNodeRefs();
					nodeservReadNodeRefFile();
				}
				stringFree(s);
				thispipe->inhandshake = 0;
				thispipe->IOPipe.status |= PSTATUS_READY;
			} else {
				if(nodetransget == 0) {
					thispipe->IOPipe.backPipe->inBuffer->size = 0;
				}
			}
		} else {
			LOGDEBUGTRAFFIC(stringJoinMany(
					"pipenodetransRead: ",
					ptrToString(thispipe),
					", read bytes:",
					intToHexString(thispipe->IOPipe.backPipe->inBuffer->size),
				NULL));
			thispipe->IOPipe.inBuffer = dblockMoveAll(thispipe->IOPipe.inBuffer, thispipe->IOPipe.backPipe->inBuffer);
		}
	}
}

void pipenodetransWrite(PipeNodeTrans *thispipe, Pipe **errPipe) {
	FileHandle *fh;
	int c;
	if(thispipe->outhandshake == 1) {
		//todo: logging
		if(nodetranssend != 0 && !isStringBlank(nodetransfile)) {
			//todo: error checkking/logging
			fh = fileOpen(nodetransfile, "r");
			if(fh != NULL) {
				while(!fileEOF(fh) && !fileError(fh)) {
					c = fileReadChar(fh);
					if(c == EOF) {
						break;
					}
					if(c != 0) {
						thispipe->IOPipe.backPipe->outBuffer = dblockAppendByte(thispipe->IOPipe.backPipe->outBuffer, (char) c);
					}
				}
				fileClose(fh);
			}
			//thispipe->IOPipe.backPipe->outBuffer = dblockAppendBuffer(thispipe->IOPipe.backPipe->outBuffer, db);
		}
		thispipe->IOPipe.backPipe->outBuffer = dblockAppendByte(thispipe->IOPipe.backPipe->outBuffer, 0);
		thispipe->outhandshake = 0;
	} else {
		LOGDEBUGTRAFFIC(stringJoinMany(
				"pipenodetransWrite: ",
				ptrToString(thispipe),
				", write bytes:",
				intToHexString(thispipe->IOPipe.outBuffer->size),
			NULL));
		thispipe->IOPipe.backPipe->outBuffer = dblockMoveAll(thispipe->IOPipe.backPipe->outBuffer, thispipe->IOPipe.outBuffer);
	}
	*errPipe = pipeGenericWrite(thispipe->IOPipe.backPipe);
}


void pipenodetransAttach(PipeNodeTrans *thispipe) {

}

void pipenodetransDetach(PipeNodeTrans *thispipe) {
	pipenodetransFree(thispipe);
}

void pipenodetransClose(PipeNodeTrans *thispipe) {
}

void pipenodetransStatus(PipeNodeTrans *thispipe, int *status) {
	//*status &= ~PSTATUS_READ;
}
