/***************************** 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 <fstream>
#include <iostream>
#include <sstream>

#include "fstream_mars_fix.h"

#include <stdio.h>
#include <gdbm.h>
#include <fcntl.h>
#include <math.h>
#include <ctype.h>
#include <Metview.h>
#include "station.h"
#include "utils.h"

#include "MvException.h"

#define MAX_LIST 30


const int cBUFSIZ = 100;
static char buf[cBUFSIZ];

extern "C" {
GDBM_FILE db = nullptr;
}

int same(const char* p, const char* q)
{
    /* check if station matches with user entry. */
    while (*p) {
        int x = islower(*p) ? toupper(*p) : *p;
        int y = islower(*q) ? toupper(*q) : *q;

        //-- '/' chars have been converted: ignore them!
        if (x != y && x != '/' && y != '/')
            return 0;

        p++;
        q++;
    }

    return 1;
}

int inbox(double lat, double lon, double north, double west, double south, double east)
{
    /* check if chosen station is in the user box. */

    while (east > 540.0)
        east -= 360.0;
    while (west > 540.0)
        west -= 360.0;

    while (east < -180.0)
        east += 180.0;
    while (west < -180.0)
        west += 180.0;

    if (east >= 360.0 && west > 360.0) {
        east -= 360.0;
        west -= 360.0;
    }

    if (east >= 0.0 && west <= 0.0) {
        east += 360.0;
        west += 360.0;
        lon += 360.0;
    }

    if (east < 0.0 && west > 0.0) {
        east += 360.0;
        west += 180.0;
        lon += 360.0;
    }

    if (lat > north || lat < south)
        return 0;

    if (lon > east || lon < west)
        return 0;

    return 1;
}

#if 0
//-- this function now in Mars (980429/vk) --//
char *upcase(const char *p)
{
	static char buf[1024];
	int i = 0;

	while(*p)
	{
		if(islower(*p))
			buf[i++] = toupper(*p);
		else
			buf[i++] = *p;
		p++;
	}
	buf[i] = 0;
	return buf;
}
#endif

char* nice_name(const char* p)
{
    /* Write station name nicely with first character(s) as upper character */

    static char buf[250];
    int i        = 0;
    int is_first = 1;

    while (*p) {
        if (isalpha(*p) && isupper(*p) && !is_first) {
            buf[i++] = tolower(*p);  //-- uppercase letter: copy to lower case
        }
        else {
            if (*p == '/')  //-- '/' is list separator: replace with '-'
            {
                buf[i++] = '-';
            }
            else {
                buf[i++] = *p;
            }
        }
        is_first = !isalpha(*p);  //-- starting a new word?
        p++;                      //-- next character
    }

    buf[i] = 0;  //-- terminate string

    for (int j = i - 1; j > 0; --j)  //-- remove possible trailing spaces
    {
        if (buf[j] != ' ')
            break;
        buf[j] = '\0';
    }

    return buf;
}


int open_database(char c)
{
    char database[1024];
    int blocksize = 0; /* less than 512 forces the system default */
    sprintf(database, "%s-%c.db", getenv("METVIEW_STATIONS"), c);
    db = gdbm_open(database, blocksize, GDBM_READER, 0777, nullptr); /* last arg is pointer to callback fn */

    if (db == nullptr)
        return 1;
    else
        return 0;
}

int open_EPS_stationfile(std::ifstream*& EPS_file)
{
    //-- first try to open the real-time cached station file --
    if (!open_cached_EPS_stationfile(EPS_file)) {
        //-- real-time cached file not ok => use one stored in 'etc'
        const char* rootdir = getenv("METVIEW_DIR_SHARE");
        Cached path         = Cached(rootdir) + "/etc/EPS_stations";
        std::cout << "Opening EPS stationfile in 'etc' directory" << std::endl;
        EPS_file = new std::ifstream((const char*)path, std::ios::in);
    }

    if (EPS_file->good()) {
        EPS_file->getline(buf, cBUFSIZ);  //-- skip first title line
        EPS_file->getline(buf, cBUFSIZ);  //-- skip second title line
        return 1;                         //-- success/true
    }
    else {
        throw MvException("Stations-> cannot open EPS stations file!");
    }
}

int open_cached_EPS_stationfile(std::ifstream*& EPS_file)
{
    //-- filename: /vol/metgram/vvvv/yyyymmddhh/eps_stat

    const char emos_version[] = "0001";
    MvDate yesterday(-1);

    std::ostringstream helper;
    helper << "/vol/metgram/"
           << emos_version
           << "/"
           << yesterday.YyyyMmDd()
           << "12"
           << "/eps_stat"
           << std::ends;

    std::string filename = helper.str();
    EPS_file             = new std::ifstream(filename.c_str(), std::ios::in);

    if (EPS_file->good()) {
        std::cout << "opened cached EPS stationfile" << std::endl;
        return 1;
    }
    else {
        delete EPS_file;
        std::cout << "Cannot open cached EPS stationfile!!!" << std::endl;
        return 0;
    }
}

int read_one_station(std::ifstream*& EPS_file, station& st)
{
    EPS_file->get(buf, 41);  //-- read numeric fields part only
    if (EPS_file->eof())
        return 0;  //-- failure/false

    std::istringstream helper(buf);  //-- read numeric values into station structure
    helper >> st.ident >> st.pos.lat >> st.pos.lon >> st.pos.station_height;

    EPS_file->getline(buf, cBUFSIZ);  //-- read rest-of-line: station name
    strcpy(st.name, buf);
    st.pos.flags[0] = '\0';  //-- 'available obs.types' flags not available

    return 1;
}
