/**
* Copyright 1981-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 <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/ipc.h>

extern int debugSet;

#include "sharedmemory.h"
#include "fortdefs.h"

#define MAC 1264

int sharedMemoryCharacteristics(
  int type,
  int truncation,
  float grid,
  int * numlat,
  size_t * size,
  key_t * key )
{
/*
// Input:
//
//   type - indicates the spectral to grid transformation:
//          SP2LL for spectral to lat/long
//          SP2RG for spectral to regular gaussian
//          SP2QG for spectral to quasi-regular (reduced) gaussian
//
//   truncation - the spectral truncation (eg 511 for T511)
//
//   grid - specifies the desired grid:
//          the grid spacing along a line of longitude for lat/long grids
//          the gaussian grid number for gaussian grids (eg 80.0 for N80)
//
// Output:
//
//   numlat - the number of latitudes from pole to pole in the grid
//
//   size - size in bytes of the transformation coefficients
//
//   key - the key for the shared memory and its associated semaphore
//
// Function returns 0 if all OK.
//
// Files setup to generate shared memory and semaphore keys are held
// in a desginated directory (see defaultDirectory below). This
// directory can be specified using environment variable SHARED_DIRECTORY.
//
*/
int status, gaussianNumber;
char defaultDirectory[] = "./";
/* char defaultDirectory[] = "/home/ma/emos/data/BlueStorm"; */
char * directory;
char filename[] = "SP2LL_Tnnnn_to_Grid_xxxxxxxxx";
char * fullFilename;
key_t Key;

/*
// Build the name of the file which is used to define a key.
// If the file does not already exist, create it.
*/
    /* directory = getenv("SHARED_DIRECTORY"); */
    directory = getenv("PPDIR");
    if( directory == NULL ) directory = defaultDirectory;
    fullFilename = (char *) malloc(strlen(directory)+strlen(filename));
    if( fullFilename == NULL ) {
      perror("malloc error");
      exit(1);
    }
    strcpy(fullFilename, directory);
    strcat(fullFilename, "/");

    switch( type) {

      case SP2LL:
        sprintf(filename,"SP2LL_T%04d_to_Grid_%09.6f",truncation,grid);
        break;

      case SP2RG:
        sprintf(filename,"SP2RG_T%04d_to_Regular_N%04.0f",truncation,grid);
        break;

      case SP2QG:
        sprintf(filename,"SP2QG_T%04d_to_Reduced_N%04.0f",truncation,grid);
        break;

      default:
        return (int) 1;
    }
    strcat(fullFilename, filename);
    
    if( DEBUG ) printf("fullFilename = %s\n", fullFilename);
    Key = ftok(fullFilename, MAC);
/*
//  If file does not exist, ..
*/
    if( Key == -1 ) {
      char * command = (char*) malloc(6+strlen(fullFilename));
      if( command == NULL ) {
        perror("malloc error");
        exit(1);
      }
      strcpy(command,"touch ");
      strcat(command,fullFilename);
      if( DEBUG ) printf("%s\n", command);
      status = system(command);
      if( status ) {
        printf("Unable to create file %s\n", fullFilename);
        perror("File creation problem");
        exit(1);
      }
      free(command);
      Key = ftok(fullFilename, MAC);
      if( Key == -1 ) {
        perror("Error getting key from newly created file");
        exit(1);
      }
    }
    free(fullFilename);

    *key = Key;
    if( DEBUG ) printf("sharedMemoryCharacteristics: Key = %0x\n", Key);
/*
// Calculate the file characteristics
*/
    switch( type) {

      case SP2LL:
        *numlat = (int)(90.0/grid + 1.0);
        break;

      case SP2RG:
      case SP2QG:
        gaussianNumber = (int) grid;
		/*
        *numlat = gaussianNumber*2;
		*/
        *numlat = gaussianNumber;
        break;

      default:
        printf("sharedMemoryCharacteristics: Type %d not yet handled\n", type);
        return (int) 1;
    }     

    *size = (((truncation+1)*(truncation+4))/2) * (*numlat) * sizeof(fortreal);
	printf("size=%ld\n",*size);
	/*
    *size = (((truncation+1)*(truncation+4))/2);
	printf("size=%d\n",*size);
	*size *= *numlat;
	printf("size=%d\n",*size);
	*size *= sizeof(fortreal);
	printf("-----size=%ld\n",*size);
	*size = 4736220160;
	printf("------size=%ld\n",*size);
	*/


    if( DEBUG ) printf("sharedMemoryCharacteristics: truncation = %d sizeof-fortreal %d numlat=%d\n", truncation,sizeof(fortreal),*numlat);
    if( DEBUG ) printf("sharedMemoryCharacteristics: Size = %ld bytes\n", *size);

    return (int) 0;
}
