/*  Copyright 1997,2001-2003 Alain Knaff.
 *  This file is part of mtools.
 *
 *  Mtools is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  Mtools is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with Mtools.  If not, see <http://www.gnu.org/licenses/>.
 *
 * Buffer read/write module
 */

#include "sysincludes.h"
#include "msdos.h"
#include "mtools.h"
#include "buffer.h"

typedef struct Buffer_t {
	Class_t *Class;
	int refs;
	Stream_t *Next;
	Stream_t *Buffer;
	
	size_t size;     	/* size of read/write buffer */
	int dirty;	       	/* is the buffer dirty? */

	size_t sectorSize;	/* sector size: all operations happen
				 * in multiples of this */
	size_t cylinderSize;	/* cylinder size: preferred alignment,
				 * but for efficiency, less data may be read */
	int ever_dirty;	       	/* was the buffer ever dirty? */
	size_t dirty_pos;
	size_t dirty_end;
	mt_off_t current;		/* first sector in buffer */
	size_t cur_size;		/* the current size */
	char *buf;		/* disk read/write buffer */
} Buffer_t;

/*
 * Flush a dirty buffer to disk.  Resets Buffer->dirty to zero.
 * All errors are fatal.
 */

static int _buf_flush(Buffer_t *Buffer)
{
	int ret;

	if (!Buffer->Next || !Buffer->dirty)
		return 0;
	if(Buffer->current < 0L) {
		fprintf(stderr,"Should not happen\n");
		return -1;
	}
#ifdef DEBUG
	fprintf(stderr, "write %08x -- %02x %08x %08x\n",
		Buffer,
		(unsigned char) Buffer->buf[0],
		Buffer->current + Buffer->dirty_pos,
		Buffer->dirty_end - Buffer->dirty_pos);
#endif

	ret = force_write(Buffer->Next,
			  Buffer->buf + Buffer->dirty_pos,
			  Buffer->current + Buffer->dirty_pos,
			  Buffer->dirty_end - Buffer->dirty_pos);
	if(ret != (signed int) (Buffer->dirty_end - Buffer->dirty_pos)) {
		if(ret < 0)
			perror("buffer_flush: write");
		else
			fprintf(stderr,"buffer_flush: short write\n");
		return -1;
	}
	Buffer->dirty = 0;
	Buffer->dirty_end = 0;
	Buffer->dirty_pos = 0;
	return 0;
}

static int invalidate_buffer(Buffer_t *Buffer, mt_off_t start)
{
	if(_buf_flush(Buffer) < 0)
		return -1;

	/* start reading at the beginning of start's sector
	 * don't start reading too early, or we might not even reach
	 * start */
	Buffer->current = ROUND_DOWN(start, Buffer->sectorSize);
	Buffer->cur_size = 0;
	return 0;
}

#undef OFFSET
#define OFFSET (start - This->current)

typedef enum position_t {
	OUTSIDE,
	APPEND,
	INSIDE,
	ERROR
} position_t;

static position_t isInBuffer(Buffer_t *This, mt_off_t start, size_t *len)
{
	if(start >= This->current &&
	   start < This->current + (mt_off_t) This->cur_size) {
		maximize(*len, This->cur_size - OFFSET);
		return INSIDE;
	} else if(start == This->current + (mt_off_t) This->cur_size &&
		  This->cur_size < This->size &&
		  *len >= This->sectorSize) {
		/* append to the buffer for this, three conditions have to
		 * be met:
		 *  1. The start falls exactly at the end of the currently
		 *     loaded data
		 *  2. There is still space
		 *  3. We append at least one sector
		 */
		maximize(*len, This->size - This->cur_size);
		*len = ROUND_DOWN(*len, This->sectorSize);
		return APPEND;
	} else {
		if(invalidate_buffer(This, start) < 0)
			return ERROR;
		maximize(*len, This->cylinderSize - OFFSET);
		maximize(*len, This->cylinderSize - This->current % This->cylinderSize);
		return OUTSIDE;
	}
}

static int buf_read(Stream_t *Stream, char *buf, mt_off_t start, size_t len)
{
	size_t length;
	mt_off_t offset;
	char *disk_ptr;
	int ret;
	DeclareThis(Buffer_t);	

	if(!len)
		return 0;	

	/*fprintf(stderr, "buf read %x   %x %x\n", Stream, start, len);*/
	switch(isInBuffer(This, start, &len)) {
		case OUTSIDE:
		case APPEND:
			/* always load until the end of the cylinder */
			length = This->cylinderSize -
				(This->current + This->cur_size) % This->cylinderSize;
			maximize(length, This->size - This->cur_size);

			/* read it! */
			ret=READS(This->Next,
				  This->buf + This->cur_size,
				  This->current + This->cur_size,
				  length);
			if ( ret < 0 )
				return ret;
			This->cur_size += ret;
			if (This->current+(mt_off_t)This->cur_size < start) {
				fprintf(stderr, "Short buffer fill\n");
				exit(1);
			}
			break;
		case INSIDE:
			/* nothing to do */
			break;
		case ERROR:
			return -1;
	}

	offset = OFFSET;
	disk_ptr = This->buf + offset;
	maximize(len, This->cur_size - offset);
	memcpy(buf, disk_ptr, len);
	return len;
}

static int buf_write(Stream_t *Stream, char *buf, mt_off_t start, size_t len)
{
	char *disk_ptr;
	DeclareThis(Buffer_t);	
	size_t offset=0;

	if(!len)
		return 0;

	This->ever_dirty = 1;

#ifdef DEBUG
	fprintf(stderr, "buf write %x   %02x %08x %08x -- %08x %08x -- %08x\n",
		Stream, (unsigned char) This->buf[0],
		start, len, This->current, This->cur_size, This->size);
	fprintf(stderr, "%d %d %d %x %x\n",
		start == This->current + This->cur_size,
		This->cur_size < This->size,
		len >= This->sectorSize, len, This->sectorSize);
#endif
	switch(isInBuffer(This, start, &len)) {
		case OUTSIDE:
#ifdef DEBUG
			fprintf(stderr, "outside\n");
#endif
			if(start % This->cylinderSize ||
			   len < This->sectorSize) {
				size_t readSize;
				int ret;

				readSize = This->cylinderSize -
					This->current % This->cylinderSize;

				ret=READS(This->Next, This->buf, This->current, readSize);
				/* read it! */
				if ( ret < 0 )
					return ret;
				if(ret % This->sectorSize) {
				  fprintf(stderr, "Weird: read size (%d) not a multiple of sector size (%d)\n", ret, (int) This->sectorSize);
				    ret -= ret % This->sectorSize;
				    if(ret == 0) {
					fprintf(stderr, "Nothing left\n");
					exit(1);
				    }
				}
				This->cur_size = ret;
				/* for dosemu. Autoextend size */
				if(!This->cur_size) {
					memset(This->buf,0,readSize);
					This->cur_size = readSize;
				}
				offset = OFFSET;
				break;
			}
			/* FALL THROUGH */
		case APPEND:
#ifdef DEBUG
			fprintf(stderr, "append\n");
#endif
			len = ROUND_DOWN(len, This->sectorSize);
			offset = OFFSET;
			maximize(len, This->size - offset);
			This->cur_size += len;
			if(This->Next->Class->pre_allocate)
				PRE_ALLOCATE(This->Next,
							 This->current + This->cur_size);
			break;
		case INSIDE:
			/* nothing to do */
#ifdef DEBUG
			fprintf(stderr, "inside\n");
#endif
			offset = OFFSET;
			maximize(len, This->cur_size - offset);
			break;
		case ERROR:
			return -1;
#ifdef DEBUG
		default:
			fprintf(stderr, "Should not happen\n");
			exit(1);
#endif
	}

	disk_ptr = This->buf + offset;

	/* extend if we write beyond end */
	if(offset + len > This->cur_size) {
		len -= (offset + len) % This->sectorSize;
		This->cur_size = len + offset;
	}

	memcpy(disk_ptr, buf, len);
	if(!This->dirty || offset < This->dirty_pos)
		This->dirty_pos = ROUND_DOWN(offset, This->sectorSize);
	if(!This->dirty || offset + len > This->dirty_end)
		This->dirty_end = ROUND_UP(offset + len, This->sectorSize);
	
	if(This->dirty_end > This->cur_size) {
		fprintf(stderr,
			"Internal error, dirty end too big dirty_end=%x cur_size=%x len=%x offset=%d sectorSize=%x\n",
			(unsigned int) This->dirty_end,
			(unsigned int) This->cur_size,
			(unsigned int) len,
			(int) offset, (int) This->sectorSize);
		fprintf(stderr, "offset + len + grain - 1 = %x\n",
				(int) (offset + len + This->sectorSize - 1));
		fprintf(stderr, "ROUNDOWN(offset + len + grain - 1) = %x\n",
				(int)ROUND_DOWN(offset + len + This->sectorSize - 1,
								This->sectorSize));
		fprintf(stderr, "This->dirty = %d\n", This->dirty);
		exit(1);
	}

	This->dirty = 1;
	return len;
}

static int buf_flush(Stream_t *Stream)
{
	int ret;
	DeclareThis(Buffer_t);

	if (!This->ever_dirty)
		return 0;
	ret = _buf_flush(This);
	if(ret == 0)
		This->ever_dirty = 0;
	return ret;
}


static int buf_free(Stream_t *Stream)
{
	DeclareThis(Buffer_t);

	if(This->buf)
		free(This->buf);
	This->buf = 0;
	return 0;
}

static Class_t BufferClass = {
	buf_read,
	buf_write,
	buf_flush,
	buf_free,
	0, /* set_geom */
	get_data_pass_through, /* get_data */
	0, /* pre-allocate */
	get_dosConvert_pass_through, /* dos convert */
	0, /* discard */
};

Stream_t *buf_init(Stream_t *Next, int size,
		   int cylinderSize,
		   int sectorSize)
{
	Buffer_t *Buffer;
	Stream_t *Stream;


	if(size % cylinderSize != 0) {
		fprintf(stderr, "size not multiple of cylinder size\n");
		exit(1);
	}
	if(cylinderSize % sectorSize != 0) {
		fprintf(stderr, "cylinder size not multiple of sector size\n");
		exit(1);
	}

	if(Next->Buffer){
		Next->refs--;
		Next->Buffer->refs++;
		return Next->Buffer;
	}

	Stream = (Stream_t *) malloc (sizeof(Buffer_t));
	if(!Stream)
		return 0;
	Buffer = (Buffer_t *) Stream;
	Buffer->buf = malloc(size);
	if ( !Buffer->buf){
		Free(Stream);
		return 0;
	}
	Buffer->size = size;
	Buffer->dirty = 0;
	Buffer->cylinderSize = cylinderSize;
	Buffer->sectorSize = sectorSize;

	Buffer->ever_dirty = 0;
	Buffer->dirty_pos = 0;
	Buffer->dirty_end = 0;
	Buffer->current = 0L;
	Buffer->cur_size = 0; /* buffer currently empty */

	Buffer->Next = Next;
	Buffer->Class = &BufferClass;
	Buffer->refs = 1;
	Buffer->Buffer = 0;
	Buffer->Next->Buffer = (Stream_t *) Buffer;
	return Stream;
}

