/*
 * © 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"
#include <errno.h>

err write_fieldset(fieldset *v,database *b)
{
	int i;
	err e = NOERR;

	for(i=0;i<v->count;i++)
	{

		long length;
		
		if(v->fields[i] != NULL)
		{
			field *g = get_field(v,i,packed_mem);

			if(g == NULL)
				return -1;

			if(g != NULL)
			{
				const void *buffer = field_message(g,&length);
				if(!buffer) return -1;
	
				if( (e = database_write(b,NULL,(char*)buffer,&length)) )
					return e;

				release_field(g);
			}
		}
	}
	return NOERR;

}

err handle_read(request *r,void *data)
{
	const char *s     = get_value(r,"FIELDSET",0);
	const char *f     = no_quotes(get_value(r,"SOURCE",0));
	const char *c     = no_quotes(get_value(r,"CFSPATH",0));
	fieldset    *v;
	boolean     pp = false;

	if(c && f)
	{
		marslog(LOG_WARN,"Cannot have CFSPATH and SOURCE together");
		marslog(LOG_WARN,"Ignoring CFSPATH");
		c = NULL;
	}

	if(f && ((strncmp(f,"ec:",3)==0) || (strncmp(f,"ectmp:",6)==0)))
	{
		char buf[1024];
		const char *tmp = marstmp();

		unlink(tmp);
		sprintf(buf,"$ECFS_SYS_PATH/ecp.p %s %s",f,tmp);


		marslog(LOG_INFO,"getting %s from ECFS",f);
		errno = 0;
		if(system(buf))
		{
			marslog(LOG_EROR|LOG_PERR,"Fail to execute ",buf);
			return -2;
		}
		else
			f = tmp;
	}

	if(c)
	{
		char buf[1024];
		f = marstmp();

		unlink(f);
		sprintf(buf,"ecfile -p %s get %s",c,f);


		marslog(LOG_INFO,"getting %s with ecfile",c);
		errno = 0;
		if(system(buf))
		{
			marslog(LOG_EROR|LOG_PERR,"Fail to execute ecfile");
			marslog(LOG_EROR,"Have you used cfslogin ?");
			return -2;
		}
	}

	pp = ( (count_values(r,"GRID")  != 0) || 
		   (count_values(r,"AREA")  == 4) ||
		   (count_values(r,"RESOL") != 0) || 
		   (count_values(r,"ROTATION") == 2) || 
		   (mars.accuracy > 0));

	if(pp)
	{
		marslog(LOG_INFO,"GRIB conversion needed...");
		v = pp_fieldset(f,r);
	} else v = read_fieldset(f,r);

	if(!v) return -2;

	new_variable(s,v,0);

	marslog(LOG_INFO,"%d field(s) read from file %s into '%s'",
	    v->count,c?c:f,s);

	if(count_values(r,"TARGET"))
	{
		request *s = empty_request("WRITE");
		err e;

		reqcpy(s,r);
		e = handle_write(s,data);

		free_all_requests(s);
		return e;
	}

	return NOERR;
}

err handle_write(request *r,void *data)
{
	const char *s = get_value(r,"FIELDSET",0);
	extern base_class *targetbase;
	err e;
	variable *v = find_variable(s);
	database *target;

	if(!v) {
		marslog(LOG_EROR,"Fieldset not found: '%s'",s);
		return -1;
	}

	if(v->scalar)
	{
		marslog(LOG_EROR,"WRITE failed. Field '%s' is a scalar (%g)",
		    s,v->val);
		return -1;
	}

	target = database_open(targetbase,NULL,r,NULL,WRITE_MODE);

	if(target == NULL)
		return -1;

	e = write_fieldset(v->fs,target);

	database_close(target);

	if(e) return e;

	marslog(LOG_INFO,"WRITE %d field(s) from '%s' to file %s",
	    v->fs->count,s,get_value(r,"TARGET",0));
	return NOERR;

}
