/*
 * © Copyright 1996-2012 ECMWF.
 * 
 * This software is licensed under the terms of the Apache Licence Version 2.0
 * which can be obtained at http://www.apache.org/licenses/LICENSE-2.0. 
 * In applying this licence, ECMWF does not waive the privileges and immunities 
 * granted to it by virtue of its status as an intergovernmental organisation nor
 * does it submit to any jurisdiction.
 */

#include "mars.h"

typedef struct data {
    char *file;
    int one;
    int expect;
} data;

static data setup;

static option opts[] = {    
{NULL,"GRIBTOREQUEST_FILE","-f",NULL, t_str,sizeof(char*),OFFSET(data,file),},    
{NULL,"GRIBTOREQUEST_ONE","-1","0", t_boolean,sizeof(boolean),OFFSET(data,one),},
{NULL,"GRIBTOREQUEST_EXPECT","-e","0", t_boolean,sizeof(boolean),OFFSET(data,expect),},
};

int main(int argc, char **argv)
{
	FILE *fd = 0;
	int e = 0;
	int cnt = 0;
	long  buflen = 0;
	long length = 0;
	char *buffer = NULL;
	request *a = empty_request("GRIB");
	char buf[80];

	marsinit(&argc,argv,&setup,NUMBER(opts),opts);
	if(!setup.file)
	{
		printf("Usage: %s -1 -f <file>\n",argv[0]);
		printf("          -1 : print a single request\n");
		printf("          -f : file to process\n");
		marsexit(1);
	}

	buflen = mars.readany_buffer_size;
	length = buflen;
	buffer = reserve_mem(length);

	start_timer();
	if((fd = fopen(setup.file,"r")) == NULL)
	{
		marslog(LOG_EROR|LOG_PERR,"fopen: %s",setup.file);
		marsexit(1);
	}

	if(mars.readdisk_buffer > 0)
	{
		if(mars.readdisk_buffer > buflen)
			marslog(LOG_WARN,"Cannot use %d bytes for setvbuf, maximum size is %ld",mars.readdisk_buffer,buflen);
		else
		{
			marslog(LOG_DBUG,"Setting I/O read buffer to %d bytes",mars.readdisk_buffer);
			if(setvbuf(fd,buffer,_IOFBF,mars.readdisk_buffer))
				marslog(LOG_WARN|LOG_PERR,"setvbuf failed");
		}
	}

	while((e = _readany(fd,buffer,&length)) == NOERR)
	{
		request *g = empty_request("GRIB");
		cnt++;
		grib_to_request(g,buffer,length);
		reqmerge(a,g);
		if(!setup.one)
		{
			marslog(LOG_INFO,"GRIB number %d",cnt);
			print_all_requests(g);
		}
		free_all_requests(g);
		length = buflen;
	}

	switch(e)
	{
		case EOF:
			e = NOERR;
		case NOERR:
			if(setup.expect)
				set_value(a,"EXPECT","%d",cnt);
			if(setup.one)
				print_all_requests(a);
			marslog(LOG_INFO,"Decoded %d GRIB messages",cnt);
			break;
		case BUF_TO_SMALL:
			marslog(LOG_WARN,"Buffer is too small (%d bytes, %d needed.)", buflen,length);
			break;
		case NOT_FOUND_7777:
			marslog(LOG_EROR,"Group 7777 not found at the end of GRIB message");
			break;
		default:
			marslog(LOG_EROR,"readany: got unknown error %d",e);
			break;
	}

	if(buffer) release_mem(buffer);
	free_all_requests(a);

	stop_timer(buf);
	timer_cpu();
	if(*buf) 
		marslog(LOG_INFO,"Request time: %s",buf);

	print_memory_usage(NULL);
	marsexit(e);
}
