/*
 * © 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"

void mars_field_index_add(mars_field_index* idx, const char* name, boolean s_ok, const char* s, boolean l_ok, long l, boolean d_ok, double d)
{
	mars_grib_map* m  = NEW_CLEAR(mars_grib_map);
	m->name = strcache(name);
	m->s_ok = s_ok;
	m->s_value = strcache(s);
	m->l_ok = l_ok;
	m->l_value = l;
	m->d_ok = d_ok;
	m->d_value = d;

	if (idx->head == NULL)
		idx->head = m;
	else
		idx->tail->next = m;

	idx->tail = m;
}

mars_field_index* mars_field_index_new( off_t offset, long length )
{
	mars_field_index* idx = NEW_CLEAR( mars_field_index );
	idx->offset = offset;
	idx->length = length;
	return idx;
}

static void send_map( mstream* s, mars_grib_map* m )
{

	while ( m )
	{
		stream_write_int(s, 1);
		stream_write_string(s, m->name);

		stream_write_int(s, m->s_ok);
		if (m->s_ok) {
			stream_write_string(s, m->s_value);
			if (mars.debug) {
				marslog(LOG_DBUG, "metadata %s %s (string)", m->name, m->s_value);
			}
		}

		stream_write_int(s, m->l_ok);
		if (m->l_ok) {
			stream_write_long(s, m->l_value);
			if (mars.debug) {
				marslog(LOG_DBUG, "metadata %s %ld (long)", m->name, m->l_value);
			}
		}
		stream_write_int(s, m->d_ok);
		if (m->d_ok) {
			stream_write_double(s, m->d_value);
			if (mars.debug) {
				marslog(LOG_DBUG, "metadata %s %g (double)", m->name, m->d_value);
			}
		}

		m = m->next;
	}
	stream_write_int(s, 0);
}

err mars_field_index_send(mars_field_index* idx, mstream* s)
{
	unsigned long count = 0;
	mars_field_index* p = idx;
	while ( p )
	{
		count++;
		p = p->next;
	}
	stream_write_ulong(s, count);

	p = idx;
	while ( p )
	{
		stream_write_ulonglong(s, p->offset);
		stream_write_ulonglong(s, p->length);

		send_map(s, p->head);

		p = p->next;
	}

	if (s->error)
	{
		marslog(LOG_EROR, "Error occurred when sending GRIB index to server");
	}

	return s->error;
}

static void free_map( mars_grib_map* m )
{
	while ( m )
	{
		mars_grib_map* next = m->next;
		strfree(m->name);
		strfree(m->s_value);
		FREE( m );
		m = next;
	}
}

void mars_field_index_free( mars_field_index* idx )
{
	while ( idx )
	{
		mars_field_index* next = idx->next;
		free_map( idx->head);
		FREE( idx );
		idx = next;
	}
}

static void print_map( mars_grib_map* m )
{
	while ( m )
	{
		mars_grib_map* next = m->next;
		printf(" %s", m->name);
		if (m->s_ok) printf(" s: %s", m->s_value);
		if (m->l_ok) printf(" l: %ld", m->l_value);
		if (m->d_ok) printf(" d: %g", m->d_value);
		m = next;
	}
}

void mars_field_index_print( mars_field_index* idx )
{
	while ( idx )
	{
		mars_field_index* next = idx->next;

		printf( "offset = %lld length = %lld", idx->offset, idx->length );
		print_map( idx->head );
		printf("\n");

		idx = next;
	}
}




