#include <sys/types.h>
#include <sys/stat.h>
#include <sys/time.h>
#include <sys/vfs.h>
#include <sys/syscall.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <strings.h>
#include <unistd.h>
#include <time.h>
#include <zlib.h>
#include <errno.h>


void main(int argc, char **argv){
	FILE *in;
	FILE *tmp;
	struct timeval start;
	struct timeval end;
	int retval;
	int newfd;
	gzFile gz;
	char *p_in;
	char *p_out;
	struct stat st;
	unsigned int ori_size;
	double _start, _end,delta;
	char fname[1024];
	struct statfs fs;


	retval = statfs("/",&fs);
	printf("Retval from statfs: %d\n",retval);
	printf("FS-Size:  %llu\n",(unsigned long long)fs.f_blocks);
	printf("FS-Avail: %llu\n",(unsigned long long)fs.f_bavail);
	printf("FS-Free:  %llu\n",(unsigned long long)fs.f_bfree);


	if ( argc != 2 ){
		printf("Usage: %s <input-file>\n",argv[0]);
		exit(2);
	}
	if ( stat(argv[1],&st) ){
		printf("Cannot stat '%s'\n",argv[1]);
		exit(3);
	}
	sprintf(fname,"%s.gz",argv[1]);
	ori_size = (unsigned int)st.st_size;
	printf("File-Size: %d Bytes\n",ori_size);
	p_in = (char *)malloc(st.st_size);
	if ( p_in == NULL ){
		printf("Cannot allocate %d Bytes of memory\n",st.st_size);
		exit(4);
	}
	in = fopen(argv[1],"r");
	if ( in == NULL ){
		printf("Cannot open %s for reading\n",argv[1]);
		exit(2);
	}
	if ( fread(p_in,1,st.st_size,in) != st.st_size ){
		printf("Cannot read from %s\n",argv[1]);
		exit(2);
	}
	fclose(in);
	gettimeofday(&start,NULL);	
	tmp = tmpfile();	
	if ( tmp == NULL  ){
		printf("Cannot open tempfile\n");
		exit(44);
	}	
	printf("Tempfile: %d\n",fileno(tmp));

	gz = gzdopen(fileno(tmp),"w");
	if ( gz == NULL ){
		printf("Cannot create GZ-Stream\n");
		exit(0);
	}
	retval = gzwrite(gz,p_in,ori_size);
	if ( retval != ori_size ){
		printf("Compression failed [%d/%d]\n",retval,ori_size);
		exit(2);
	}
	newfd = dup(fileno(tmp));
	gzclose(gz);
	tmp = tmpfile();	
	if ( fstat(newfd,&st) ){
		printf("Cannot stat tempfile\n");
		exit(3);
	}	
	if ( lseek(newfd,(off_t)0,SEEK_SET) == (off_t) -1 ){
		printf("LSEEK FAILED\n");
		exit(4);
	}
	p_out = (char *)malloc(st.st_size);
	if ( p_out == NULL ){
		printf("Malloc failed for output\n");
		exit(5);
	}	
	if ( read(newfd,p_out,st.st_size) != st.st_size ){
		printf("Read failed for output\n");
		exit(5);
	}
	close(newfd);
	gettimeofday(&end,NULL);	
	_start = ((double) start.tv_sec) + (((double) start.tv_usec) / 1000000);
	_end = ((double) end.tv_sec) + (((double) end.tv_usec) / 1000000);
	delta = _end - _start;
	in = fopen(fname,"w");
	if ( in == NULL ){
		printf("Cannot create [%s]\n",fname);
		exit(2);	
	}
	retval = fwrite(p_out,1,st.st_size,in);
	fclose(in);
	printf("Compressed size: %d, Compression-time: %.05f Seconds RETVAL of WRITE: %d\n",st.st_size,delta,retval);
}
