/***************************** LICENSE START ***********************************

 Copyright 2012 ECMWF and INPE. This software is distributed under the terms
 of the Apache License version 2.0. In applying this license, ECMWF does not
 waive the privileges and immunities granted to it by virtue of its status as
 an Intergovernmental Organization or submit itself to any jurisdiction.

 ***************************** LICENSE END *************************************/

#include <mars.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <sys/stat.h>
#include <UtilitiesC.h>
#include <assert.h>
#include <ctype.h>

#define ENSIZE 32 /* extra characteres to be added to the filename lenght */

char* UtRandomName(const char* path, const char* name)
{
    static int count = 0;
    char* fname = (char*)malloc(strlen(path) + strlen(name) + ENSIZE);
    sprintf(fname, "%s/%d%s%d", path, getpid(), name, ++count);
    return fname;
}

char* UtProgressiveName(const char* path, const char* name)
{
    int count = 0;
    struct stat info;
    char* fname;
    while (1) {
        fname = (char*)malloc(strlen(path) + strlen(name) + ENSIZE);
        sprintf(fname, "%s/%s %d", path, name, ++count);
        if (stat(fname, &info) != 0)
            break;
        free(fname);
    }
    return fname;
}

/* Alternative implementation that does not put spaces between the name and counter and does not repeat the name (for magics) */
char* UtProgressiveName2(const char* path, const char* name)
{
    static int count = 0;
    struct stat info;
    char* fname;
    while (1) {
        fname = (char*)malloc(strlen(path) + strlen(name) + ENSIZE);
        sprintf(fname, "%s/%s%d", path, name, ++count);
        if (stat(fname, &info) != 0)
            break;
        free(fname);
    }
    return fname;
}

char* UtPath2Name(const char* path)
{
    int i;
    int len = strlen(path), ini = -1, fin = -1;

    for (i = len - 1; i >= 0; i--) {
        if (path[i] == '/' && ini == -1)
            ini = i + 1;
        if (path[i] == '.' && ini == -1)
            fin = i - 1;
    }
    if (ini == -1)
        ini = 0;
    if (fin == -1)
        fin = len - 1;
    if (ini <= fin) {
        char* name = (char*)malloc(fin - ini + 2);
        strncpy(name, path + ini, fin - ini + 1);
        name[fin - ini + 1] = '\0';
        return name;
    }
    else
        return NULL;
}


/* Touch file */

int UtTouch(const char* dir, const char* fname)
{
    FILE* fp;
    char* full_name = (char*)malloc(strlen(dir) + strlen(fname) + 2);
    sprintf(full_name, "%s/%s", dir, fname);

    fp = fopen(full_name, "w");
    if (fp)
        fclose(fp);
    free(full_name);
    return 1;
}

int UtIsValidVisDef(const char* pathname)
{
    struct stat descr;
    if (stat(pathname, &descr) != 0)
        return 0;
    if (S_ISDIR(descr.st_mode))
        return 0;
    return 1;
}
void UtWriteCmd(FILE* fp, const char* cmd)
{
    fprintf(fp, "\n%s", cmd);
}

void UtWritePar(FILE* fp, const char* par, const char* value)
{
    if (value)
        if (*value == '/')
            fprintf(fp, ",\n\t%s = '%s'", par, value);
        else
            fprintf(fp, ",\n\t%s = %s", par, value);
    else
        fprintf(fp, ",\n\t%s = Default", par);
}

void UtWriteLiteralPar(FILE* fp, const char* par, const char* value)
{
    fprintf(fp, ",\n\t%s = '%s'", par, value);
}

void UtWriteIntPar(FILE* fp, const char* par, int value)
{
    fprintf(fp, ",\n\t%s = %d", par, value);
}

void UtWriteFloatPar(FILE* fp, const char* par, float value)
{
    fprintf(fp, ",\n\t%s = %f", par, value);
}


/**************************************************
 * FUNCTION putenv: putenv_ from FORTRAN
 *****************************************************
 *
 * Purpose:      Set environment variable
 *			safely (not destroing) string
 *
 *
 * Function returns:  N0n-zero if failing;
 *                    Zero if set;
 */

#ifdef FORTRAN_NO_UNDERSCORE
#define cputenv_ cputenv
#endif

#define PROC
PROC fortint cputenv_(char* env, fortint length)
{
    fortint i;
    char* p;

    p = (char*)malloc(length + 1);
    strncpy(p, env, length);
    p[length] = '\0';

    i = putenv(p);
    return i;
}
/************************************************
FUNCTION : Write Icon Description File
*************************************************
*
*  Purpose: Write a description file so that MetviewUI
*           can later recognize this file
*
*/


void UtWriteIconDescriptionFile(const char* fileName, const char* iconClass)
{
    request* reqst;
    FILE* fp;

    assert(fileName != 0);
    assert(iconClass != 0);


    fp = fopen(fileName, "w");

    if (fp) {
        reqst = empty_request("USER_INTERFACE");
        set_value(reqst, "ICON_NAME", mbasename(fileName));
        set_value(reqst, "ICON_CLASS", iconClass);

        save_all_requests(fp, reqst);
        fclose(fp);
        free_all_requests(reqst);
    }
}
/* replace the %? in the command */

void UtWritePrinterCmd(char* cmd,
                       const char* user_cmd,
                       const char* printer,
                       const char* ncopies,
                       const char* fname)
{
    char filename[2000];
    int i = -1, j = -1;
    while (user_cmd[++i]) {
        if (user_cmd[i] == '%') {
            switch (user_cmd[i + 1]) {
                case 'p':
                    strcat(cmd, printer);
                    break;

                case 'n':
                    strcat(cmd, ncopies);
                    break;

                case 'f':
                    if (user_cmd[i - 1] != '"' && user_cmd[i - 1] != '\'') {
                        sprintf(filename, "\"%s\"", fname);
                    }
                    else
                        sprintf(filename, "%s", fname);
                    strcat(cmd, filename);
                    break;

                default:
                    cmd[++j] = '%';
                    cmd[++j] = user_cmd[i + 1];
                    cmd[++j] = '\0';
            }
            i++;
            j = strlen(cmd) - 1;
        }
        else {
            cmd[++j] = user_cmd[i];
            cmd[j + 1] = '\0';
        }
    }
    printf("UtWritePrinterCmd ... cmd = %s\n", cmd);
}

void UtWritePreviewCmd(char* previewCmd, const char* previewerName, const char* outFileName)
{
    int j = 0;

    /* copy the previewer name in lower case characters */

    while (previewerName[j] != '\0') {
        previewCmd[j] = toupper(previewerName[j]);
        j++;
    }

    previewCmd[j] = ' ';

    /* Append the output file Name */
    strcat(previewCmd, outFileName);


    printf("UtWritePreviewCmd ... cmd = %s\n", previewCmd);
}

/* Fernando Ii 05/00
   Truncates a float number to have
   only 2 decimal digits.
*/
double t2d(double value)
{
    int bb = value * 100.;
    return (double)bb / 100.;
}


/* vk/020802 */

int localWmoSiteNumber(void)
{
    int n = 98; /* default 98 = ECMWF */

    const char* en = getenv("WMO_SITE_NR");
    if (en) {
        if (*en == '0')
            ++en; /* skip leading zero */
        n = atoi(en);
    }

    return n;
}
