/*-------------------------------------------------------------------------
 * drawElements Stream Library
 * ---------------------------
 *
 * Copyright 2014 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 *//*!
 * \file
 * \brief Buffered and threaded input and output streams
 *//*--------------------------------------------------------------------*/

#include "deThreadStream.h"
#include "deStreamCpyThread.h"
#include "deRingbuffer.h"
#include "stdlib.h"

typedef struct deThreadInStream_s
{
	deRingbuffer*		ringbuffer;
	deInStream*			input;
	deInStream			consumerStream;
	deOutStream			producerStream;
	deThread			thread;
	int					bufferSize;
} deThreadInStream;

typedef struct deThreadOutStream_s
{
	deRingbuffer*		ringbuffer;
	deInStream			consumerStream;
	deOutStream			producerStream;
	deStreamCpyThread*	thread;
} deThreadOutStream;

static void inStreamCopy (void* arg)
{
	deThreadInStream* threadStream = (deThreadInStream*)arg;

	deUint8* buffer = malloc(sizeof(deUint8) * (size_t)threadStream->bufferSize);

	for(;;)
	{
		deInt32 read	= 0;
		deInt32 written	= 0;
		deStreamResult readResult = DE_STREAMRESULT_ERROR;

		readResult = deInStream_read(threadStream->input, buffer, threadStream->bufferSize, &read);
		DE_ASSERT(readResult != DE_STREAMRESULT_ERROR);
		while (written < read)
		{
			deInt32 wrote = 0;

			/* \todo [mika] Handle errors */
			deOutStream_write(&(threadStream->producerStream), buffer, read - written, &wrote);

			written += wrote;
		}

		if (readResult == DE_STREAMRESULT_END_OF_STREAM)
		{
			break;
		}
	}

	deOutStream_flush(&(threadStream->producerStream));
	deRingbuffer_stop(threadStream->ringbuffer);
	free(buffer);

}

static deStreamResult threadInStream_read (deStreamData* stream, void* buf, deInt32 bufSize, deInt32* numRead)
{
	deThreadInStream* threadStream = (deThreadInStream*)stream;
	return deInStream_read(&(threadStream->consumerStream), buf, bufSize, numRead);
}

static const char* threadInStream_getError (deStreamData* stream)
{
	deThreadInStream* threadStream = (deThreadInStream*)stream;

	/* \todo [mika] Add handling for errors on thread stream */
	return deInStream_getError(&(threadStream->consumerStream));
}

static deStreamStatus threadInStream_getStatus (deStreamData* stream)
{
	deThreadInStream* threadStream = (deThreadInStream*)stream;

	/* \todo [mika] Add handling for status on thread stream */
	return deInStream_getStatus(&(threadStream->consumerStream));
}

/* \note [mika] Used by both in and out stream */
static deStreamResult threadStream_deinit (deStreamData* stream)
{
	deThreadInStream* threadStream = (deThreadInStream*)stream;

	deRingbuffer_stop(threadStream->ringbuffer);

	deThread_join(threadStream->thread);
	deThread_destroy(threadStream->thread);

	deOutStream_deinit(&(threadStream->producerStream));
	deInStream_deinit(&(threadStream->consumerStream));

	deRingbuffer_destroy(threadStream->ringbuffer);

	return DE_STREAMRESULT_SUCCESS;
}

static const deIOStreamVFTable threadInStreamVFTable = {
	threadInStream_read,
	DE_NULL,
	threadInStream_getError,
	DE_NULL,
	threadStream_deinit,
	threadInStream_getStatus
};

void deThreadInStream_init (deInStream* stream, deInStream* input, int ringbufferBlockSize, int ringbufferBlockCount)
{
	deThreadInStream* threadStream = DE_NULL;

	threadStream = malloc(sizeof(deThreadInStream));
	DE_ASSERT(threadStream);

	threadStream->ringbuffer = deRingbuffer_create(ringbufferBlockSize, ringbufferBlockCount);
	DE_ASSERT(threadStream->ringbuffer);

	threadStream->bufferSize = ringbufferBlockSize;
	threadStream->input = input;
	deProducerStream_init(&(threadStream->producerStream), threadStream->ringbuffer);
	deConsumerStream_init(&(threadStream->consumerStream), threadStream->ringbuffer);

	threadStream->thread		= deThread_create(inStreamCopy, threadStream, DE_NULL);
	stream->ioStream.vfTable	= &threadInStreamVFTable;
	stream->ioStream.streamData = threadStream;
}

static deStreamResult threadOutStream_write (deStreamData* stream, const void* buf, deInt32 bufSize, deInt32* numWritten)
{
	deThreadOutStream* threadStream = (deThreadOutStream*)stream;
	return deOutStream_write(&(threadStream->producerStream), buf, bufSize, numWritten);
}

static const char* threadOutStream_getError (deStreamData* stream)
{
	deThreadOutStream* threadStream = (deThreadOutStream*)stream;

	/* \todo [mika] Add handling for errors on thread stream */
	return deOutStream_getError(&(threadStream->producerStream));
}

static deStreamStatus threadOutStream_getStatus (deStreamData* stream)
{
	deThreadOutStream* threadStream = (deThreadOutStream*)stream;

	/* \todo [mika] Add handling for errors on thread stream */
	return deOutStream_getStatus(&(threadStream->producerStream));
}

static deStreamResult threadOutStream_flush (deStreamData* stream)
{
	deThreadOutStream* threadStream = (deThreadOutStream*)stream;

	return deOutStream_flush(&(threadStream->producerStream));
}

static const deIOStreamVFTable threadOutStreamVFTable = {
	DE_NULL,
	threadOutStream_write,
	threadOutStream_getError,
	threadOutStream_flush,
	threadStream_deinit,
	threadOutStream_getStatus
};

void deThreadOutStream_init (deOutStream* stream, deOutStream* output, int ringbufferBlockSize, int ringbufferBlockCount)
{
	deThreadOutStream* threadStream = DE_NULL;

	threadStream = malloc(sizeof(deThreadOutStream));
	DE_ASSERT(threadStream);

	threadStream->ringbuffer = deRingbuffer_create(ringbufferBlockSize, ringbufferBlockCount);
	DE_ASSERT(threadStream->ringbuffer);

	deProducerStream_init(&(threadStream->producerStream), threadStream->ringbuffer);
	deConsumerStream_init(&(threadStream->consumerStream), threadStream->ringbuffer);

	threadStream->thread		= deStreamCpyThread_create(&(threadStream->consumerStream), output, ringbufferBlockSize);
	stream->ioStream.vfTable	= &threadOutStreamVFTable;
	stream->ioStream.streamData = threadStream;
}

