/*
 * © 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 <ctype.h>
#include <sys/types.h>

static char *scan_file(const char *file)
{
	FILE *f = fopen(file,"r");
	int len;
	int max;
	unsigned char c = ' ';

	union {
		char  c;
		short s;
		long  l;
		char  ch[8];
	} buf;

	if(f == NULL)
		return "BAD";

	memset(&buf,0,sizeof(buf));


	if((len = fread((char*)&buf,1,sizeof(buf),f)) < 0)
	{
		fclose(f);
		marslog(LOG_DBUG,"Bad len '%d' while reading '%s'",len,file);
		return "BAD";
	}

	if(strncmp(buf.ch,"%!",2) == 0)
	{
		fclose(f);
		return "PSFILE";
	}

	if(strncmp(buf.ch,"#!",2) == 0)
	{
		fclose(f);
		return "SHELL";
	}

	if(strncmp(buf.ch,"GRIB",4) == 0)
	{
		fclose(f);
		return "GRIB";
	}

	if(strncmp(buf.ch,"TIDE",4) == 0)
	{
		fclose(f);
		return "GRIB";
	}

	if(strncmp(buf.ch,"BUDG",4) == 0)
	{
		fclose(f);
		return "GRIB";
	}

	if(strncmp(buf.ch,"BUFR",4) == 0)
	{
		fclose(f);
		return "BUFR";
	}

	if(strncmp(buf.ch,"%!",2) == 0)
	{
		fclose(f);
		return "POSTSCRIPT";
	}

	if(strncmp(buf.ch,"#GEO",4) == 0)
	{
		fclose(f);
		return "GEOPOINTS";
	}

	if(strncmp(buf.ch,"#LLM",4) == 0)
	{
		fclose(f);
		return "LLMATRIX";
	}

	if(strncmp(buf.ch+2,"GRIB",4) == 0)
	{
		fclose(f);
		return "GRIB";
	}

	if(strncmp(buf.ch+4,"GRIB",4) == 0)
	{
		fclose(f);
		return "GRIB";
	}

	if(strncmp(buf.ch+2,"BUFR",4) == 0)
	{
		fclose(f);
		return "BUFR";
	}

	if(strncmp(buf.ch+4,"BUFR",4) == 0)
	{
		fclose(f);
		return "BUFR";
	}

	if(strncmp(buf.ch,"CDF",3) == 0)
	{
		fclose(f);
		return "NETCDF";
	}

	rewind(f);

	max = 4096; /* 4 K */
	while(max-->0 && !feof(f))
	{
		fread((char*)&c,1,1,f);
		if(!isprint(c) && !isspace(c))
		{
			fclose(f);
			return "BINARY";
		}
	}

	fclose(f);
	return "NOTE";
}

char *guess_class(const char *file)
{

	struct stat buf;

	if(stat(file,&buf) <0)
		return "BAD";

	switch(buf.st_mode & S_IFMT)
	{
	case S_IFDIR:
		return "FOLDER";

	case S_IFREG:
		return scan_file(file);

	default:
		return "SPECIAL";
	}

}
