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

/*

M.Fuentes
ECMWF Mar-97

(Groups auxiliary verbs as: FLUSH, LIST, REMOVE, ...
*/

#include <errno.h>
#include "mars.h"

struct cntl {
    char* verb;
    int code;
} controls[] = {
    {
        "FLUSH",
        CNTL_FLUSH,
    },
    {
        "LIST",
        CNTL_LIST,
    },
    {
        "BROWSE",
        CNTL_LIST,
    },
    {
        "REMOVE",
        CNTL_REMOVE,
    },
    {
        "ATTACH",
        CNTL_ATTACH,
    },
    {
        "STAGE",
        CNTL_STAGE,
    },
    {
        "STORE",
        CNTL_STORE,
    },
    {
        "GET",
        CNTL_LIST,
    },
    {
        NULL,
        0,
    },
};

static err control(const request* b, request* r, int code) {
    database* bout;
    err ret;
    const char* name = 0;
    request* cache   = 00;

    bout = openbase(b, r, &name, &cache, READ_MODE);
    if (!bout)
        return -2;

    ret = database_control(bout, code, r, 0);
    database_close(bout);

    marslog(LOG_INFO, "Request performed on database '%s'", name);

    return ret;
}

err handle_control(request* r, void* data) {
    const char* s = get_value(r, "DATABASE", 0);
    const char* v = request_verb(r);
    int visit     = 0;

    if (s == 0) {
        marslog(LOG_EROR, "%s needs DATABASE set", v);
        return -5;
    }
    else {
        int i    = 0;
        int code = 0;
        err last = 0;


        /* Lookup control code */

        while (controls[i].verb)
            if (EQ(v, controls[i].verb))
                break;
            else
                i++;

        if (!controls[i].verb) {
            marslog(LOG_EROR, "%s confused MARS", v);
            return -5;
        }
        else
            code = controls[i].code;

        i = 0;
        while ((s = get_value(r, "DATABASE", i++))) {
            const request* b = findbase(s, r);
            if (!b)
                return -2;

            last = control(b, r, code);
            if (last == NOERR)
                visit++;

            if (visit > 0)
                last = NOERR;
        }

        return last;
    }

    /*NOTREACHED*/
    return 0;
}
