/*
 * © 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"

#define BUFSIZE 300 * 1024

char buffer[BUFSIZE];
char prod = 0;

static int flush(char* tmp, base_class* c) {
    long len;
    FILE* f;
    err e = 0;
    database* b;
    request* r = empty_request(NULL);
    int cnt    = 0;
    int dups   = 0;

    marslog(LOG_INFO, "flushing...");

    b = database_open(c, NULL, NULL, NULL, WRITE_MODE);
    if (!b)
        marslog(LOG_EXIT, "database_open failed");


    f = fopen(tmp, "r");
    if (f == NULL) {
        marslog(LOG_EROR | LOG_PERR, "%s", tmp);
        return -2;
    }

    unlink(tmp);

    len = sizeof(buffer);

    if (prod == 'G') {
        while ((e = _readany(f, buffer, &len)) == NOERR) {
            grib_to_request(r, (char*)buffer, len);
            if (mars.debug)
                print_one_request(r);
            e = database_write(b, r, buffer, &len);
            if (e == DUPLICATE_ERR) {
                dups++;
                e = 0;
            }
            if (e)
                break;
            len = sizeof(buffer);
            cnt++;
        }
        if (e == EOF)
            e = 0;
    }
    else {
        while ((e = _readbufr(f, buffer, &len)) == NOERR) {
            bufr_to_request(r, (char*)buffer, len);
            if (mars.debug)
                print_one_request(r);
            e = database_write(b, r, buffer, &len);
            if (e == DUPLICATE_ERR) {
                dups++;
                e = 0;
            }
            if (e)
                break;
            len = sizeof(buffer);
            cnt++;
        }
        if (e == EOF)
            e = 0;
    }
    fclose(f);
    database_close(b);
    marslog(LOG_INFO, "Written %d messages. %d duplicates", cnt - dups, dups);
    return e;
}

#define INC 1024 * 20

void feedtask(int soc, int count, void* data) {
    base_class* driver = (base_class*)data;
    long len;
    char* tmp  = marstmp();
    FILE* f    = fopen(tmp, "w");
    long total = 0;
    long val   = INC;

    while ((len = read(soc, buffer, sizeof(buffer))) > 0) {
        total += len;
        if (prod == 0)
            prod = buffer[0];

        if ((fwrite(buffer, 1, len, f) != len)) {
            marslog(LOG_EROR | LOG_PERR, "error writting %s", tmp);
            fclose(f);
            flush(tmp, driver);
            f = fopen(tmp, "w");
            fwrite(buffer, 1, len, f);
        }

        if (total > val) {
            val += INC;
            marslog(LOG_INFO, "%sbytes received", bytename(total));
        }
    }

    fclose(f);
    flush(tmp, driver);
    unlink(tmp);
}
