/*******************************************************************************
 * Copyright (c) 2005, 2007 Intel Corporation.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *    Vishnu K Naikawadi, Intel - Initial API and Implementation
 *
 * $Id: FileDataProcessor.cpp,v 1.12 2007/12/07 04:04:04 jkubasta Exp $
 *
 *******************************************************************************/ 


#include <iostream>
#include <stdio.h>

#include "tptp/TPTPUtils.h"
#include "tptp/TPTPCommon.h"
#include "tptp/NoLog.h"
#include "tptp/client/FileDataProcessor.h"
#include "tptp/dime.h"



using namespace std;


FileDataProcessor::FileDataProcessor()
{
	tptp_initializeLock(&fileOpListLock);
	tptp_list_init(&fileOpList);
}



FileDataProcessor::~FileDataProcessor()
{
	tptp_list_clear(&fileOpList);
	tptp_deleteLock(&fileOpListLock);
}

tptp_int32 FileDataProcessor::findFileRecordByName(const char *fileName, tptp_file_t *fileRec)
{
	tptp_node_t*    node;
	tptp_file_t* tmpFileRec;

	tptp_getReadLock(&fileOpListLock);
	for (node = fileOpList.head; node != 0; node = node->next )
	{
		tmpFileRec = (tptp_file_t*)node->data;
		if ( isEqualString(tmpFileRec->name, fileName))
		{
			fileRec->fp = tmpFileRec->fp;
			fileRec->semaphore = tmpFileRec->semaphore;
			tptp_releaseReadLock(&fileOpListLock);
			return 0;
		}
	}
	tptp_releaseReadLock(&fileOpListLock);
	return -1;
}


void FileDataProcessor::initializeFileTransfer(char *fileName, FILE *fp)
{
	tptp_file_t* fileRec;

	fileRec = (tptp_file_t *) tptp_malloc(sizeof(tptp_file_t));

	fileRec->name = fileName;
	fileRec->fp   = fp;

	fileRec->semaphore = (Semaphore_t *) tptp_malloc(sizeof(Semaphore_t));

	tptp_int32 rc = tptp_initializeSemaphore(fileRec->semaphore);
	tptp_getWriteLock(&fileOpListLock);
	tptp_list_add(&fileOpList, fileRec);
	tptp_releaseWriteLock(&fileOpListLock);
}

void FileDataProcessor::waitForFileComplete(char *fileName)
{

	tptp_file_t fileRec;
	tptp_int32 rc;

	rc = findFileRecordByName(fileName, &fileRec);

	if (rc != -1) {
		rc = tptp_waitSemaphore(fileRec.semaphore);
		tptp_deleteSemaphore(fileRec.semaphore);
		tptp_getWriteLock(&fileOpListLock);
		tptp_list_remove(&fileOpList, &fileRec);
		tptp_releaseWriteLock(&fileOpListLock);
	}
}

/**
 * Handle the data coming 
 */
void FileDataProcessor::incomingData(char buffer[], tptp_int32 length, DIME_HEADER_PTR_T dimeHeader)
{
	tptp_int32 rc;
	char* fileName;
	tptp_file_t fileRec;
	tptp_int32 dime_length;

	if (!is_valid_header(dimeHeader, dimeHeader->id_length+length+sizeof(DIME_HEADER_T))) {
		TPTP_LOG_ERROR_MSG1("not a valid header", length);
		return;
	}
	fileName = GET_DIME_ID(dimeHeader);
	dime_length = GET_DIME_LENGTH(dimeHeader);

	rc = findFileRecordByName(fileName, &fileRec);
	if (rc != -1) {
		fwrite((void *)buffer, 1, length, fileRec.fp);
		TPTP_LOG_DEBUG_MSG1("Wrote %d bytes of data", length);
		//TPTP_LOG_DEBUG_MSG1("The data is - %s", buffer);
		/* Post the semaphore when we get to the last record */
		if (IS_DIME_END_RECORD(dimeHeader)) {
			TPTP_LOG_DEBUG_MSG("The end flag has arrived");
			tptp_postSemaphore(fileRec.semaphore);
		}
	}
}


/**
 * Invalid Data Type
 */
void FileDataProcessor::invalidDataType(char data[], tptp_int32 length)
{
	cout<<"Error: File data processor received invalid data type."<<endl;

}
/**
 * Waiting for data
 */
void FileDataProcessor::waitingForData()
{

	//cout<<"FileDataProcessor::waitingForData() called"<<endl;

}
