//
//p-dummy.c
//
//This is dummy pipe. It will just pass data along doing no filter/processing.
//
//This file can be used as a template for other protocols.
//
//
//-UserX 2001/12/06

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

#include "base/dblock.h"
#include "base/mem.h"
#include "base/str.h"
#include "pipe/closdlay.h"
#include "base/logger.h"
#include "crypt/random.h"

PipeCloseDelay blankpipeclosedelay = BLANKPIPECLOSEDELAY;

int closedelay = 0;

Pipe *pipeclosedelayMake(char *pipename, char *options) {
	PipeCloseDelay *thispipe = memCopy(&blankpipeclosedelay, sizeof(PipeCloseDelay), "PipeCloseDelay", NULL);
	pipeInitFunctions((Pipe *) thispipe, 
			(PipeFuncIn) pipeclosedelayRead, (PipeFuncOut) pipeclosedelayWrite, 
			(PipeFuncAttach) pipeclosedelayAttach, (PipeFuncDetach) pipeclosedelayDetach, 
			(PipeFuncClose) pipeclosedelayClose, (PipeFuncStatus) pipeclosedelayStatus);
	pipeInit((Pipe *) thispipe);
	thispipe->IOPipe.status |= PSTATUS_READY;
	return (Pipe *)thispipe;
}

void pipeclosedelayFree(PipeCloseDelay *thispipe) {
	pipeFree(&thispipe->IOPipe);
	memFree(thispipe);
}

void pipeclosedelayRead(PipeCloseDelay *thispipe, Pipe **errPipe) {
	*errPipe = pipeGenericRead(thispipe->IOPipe.backPipe);
	if(*errPipe == NULL) {
		LOGDEBUGTRAFFIC(stringJoinMany(
				"pipeclosedelayRead: ",
				ptrToString(thispipe),
				", read bytes:",
				intToHexString(thispipe->IOPipe.backPipe->inBuffer->size),
			NULL));
		thispipe->IOPipe.inBuffer = dblockMoveAll(thispipe->IOPipe.inBuffer, thispipe->IOPipe.backPipe->inBuffer);
	}
}

void pipeclosedelayWrite(PipeCloseDelay *thispipe, Pipe **errPipe) {
	LOGDEBUGTRAFFIC(stringJoinMany(
			"pipeclosedelayWrite: ",
			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 pipeclosedelayAttach(PipeCloseDelay *thispipe) {

}

void pipeclosedelayDetach(PipeCloseDelay *thispipe) {
	pipeclosedelayFree(thispipe);
}

void pipeclosedelayClose(PipeCloseDelay *thispipe) {
}

void pipeclosedelayStatus(PipeCloseDelay *thispipe, int *status) {
	if((*status & PSTATUS_CLOSED) != 0) {
		if(thispipe->closedtime == 0) {
			thispipe->closedtime = time(NULL);
			thispipe->delay = randomint(closedelay + 1) + closedelay / 2;
			LOGDEBUG(stringJoinMany(
					"pipeclosedelayStatus: ",
					ptrToString(thispipe),
					", delay time (seconds):",
					intToString(thispipe->delay),
				NULL));
		}
		if(time(NULL) < thispipe->closedtime + thispipe->delay) {
			*status &= ~PSTATUS_CLOSED;
		}
	}
	//*status &= ~PSTATUS_READ;
}
