/*
 * © 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 "mars_client_config.h"
#include "mars_client_version.h"

#ifdef ODB_SUPPORT
#include "odc/api/odc.h"
#endif

err pproc_print_version();

#if mars_client_HAVE_FDB5
const char* fdb5_version_str();
const char* metkit_version_str();
#endif

#if mars_client_HAVE_FDB5 || mars_client_HAVE_ODB
const char* eckit_version_str();
#endif

#if defined(__linux__) && defined(USEPGI)
int __argc_save;
char** __argv_save;
static int zz = 0;
#endif


int main(int argc, char* argv[]) {
    /* char s[10]; */
    request *r, *p;
    err e                 = 0;
    long long bytes       = 0;
    long grib_api_version = grib_get_api_version();
    char* mars_home       = getenv("MARS_HOME");

#if defined(__linux__) && defined(USEPGI)
    __argc_save = argc;
    __argv_save = argv;
    pghpf_init(&zz);
#endif

#if defined(xfujitsux) && defined(ECMWF)
    char* samp = getenv("VPP_STATS");
    if (samp)
        sampstart_();
#endif

    argv[0] = "mars";

    marsinit(&argc, argv, NULL, 0, NULL);

    mars.verbose = true;
    /* mars.savecalc = true; */

    char msg[256];

    strcpy(msg, "Welcome to MARS");

    marslog(LOG_INFO, msg);

    if (mars.show_hosts) {
        if (mars_home != NULL)
            marslog(LOG_INFO, "MARS_HOME=%s", mars_home);
    }

    marslog(LOG_INFO, "MARS Client build stamp: %s", mars_client_buildstamp());

    marslog(LOG_INFO, "MARS Client bundle version: %s", mars_client_bundle_version_str());
#ifndef ECMWF
    marslog(LOG_INFO, "MARS Client version: %ld", marsversion());
#endif

    marslog(LOG_INFO, "package mars-client version: %s", mars_client_version_str());

    e = pproc_print_version();
    if (e != NOERR) {
        marsexit(e);
    }

#if mars_client_HAVE_ODB
    const char* odbver;
    odc_version(&odbver);
    marslog(LOG_INFO, "package odc version: %s", odbver);
#endif

#if mars_client_HAVE_FDB5
    marslog(LOG_INFO, "package fdb version: %s", fdb5_version_str());
    marslog(LOG_INFO, "package metkit version: %s", metkit_version_str());
#endif

#if mars_client_HAVE_FDB5 || mars_client_HAVE_ODB
    marslog(LOG_INFO, "package eckit version: %s", eckit_version_str());
#endif
    marslog(LOG_INFO, "package eccodes version: %ld.%ld.%ld",
            ECCODES_MAJOR_VERSION,
            ECCODES_MINOR_VERSION,
            ECCODES_REVISION_VERSION);

    if (mars.show_pid)
        marslog(LOG_INFO, "MARS Client pid: %ld", (long)getpid());

    if (mars.max_retrieve_size)
        marslog(LOG_INFO, "Maximum retrieval size is %s", bytename(mars.max_retrieve_size));

    mars.echo = (boolean)!isatty(0);
    p = r     = read_mars_request(getenv("MARS_REQUEST"));
    mars.echo = false;

    if (r == NULL)
        marslog(LOG_EXIT, "No request");

    while (r && e == NOERR) {
        request* s = r->next;
        r->next    = NULL;
        mars.current_request++;
        e       = handle_request(r, NULL);
        r->next = s;
        r       = s;
    }

    if (e == END_REQUEST)
        e = NOERR;

    if (e == NOERR)
        e = send_remote_targets();

    bytes = proc_mem();
    if (bytes)
        marslog(LOG_INFO, "Memory used: %sbyte(s)", bytename((double)bytes));

    if (e == NOERR)
        marslog(LOG_INFO, "No errors reported");
    else
        marslog(LOG_EROR, "Some errors reported (last error %d)", e);

    free_all_requests(p);


#if defined(nofujitsu) && defined(ECMWF)
    if (samp)
        sampstop_();
#endif

    marsexit(e);

    return e;
}
