/* $Cambridge: hermes/src/prayer/cmd/cmd_quota.c,v 1.5 2008/10/04 14:32:14 dpc22 Exp $ */
/************************************************
 *    Prayer - a Webmail Interface              *
 ************************************************/

/* Copyright (c) University of Cambridge 2000 - 2008 */
/* See the file NOTICE for conditions of use and distribution. */

#include "prayer_session.h"

/* ====================================================================== */

/* Slightly naughty interface to undocumented QUOTAROOT support in c-client */

#include "imap4r1.h"         

static unsigned long my_quota_active  = NIL;
static unsigned long my_quota_current = 0;
static unsigned long my_quota_limit   = 0;

static void
my_quotalist_callback(MAILSTREAM *stream, char *qroot, QUOTALIST *qlist)
{
    while (qlist) {
        if (qlist->name && !strcmp(qlist->name, "STORAGE")) {
            my_quota_current = qlist->usage;
            my_quota_limit   = qlist->limit;
            my_quota_active  = T;
        }
        qlist = qlist->next;
    }
}

static BOOL
mailstore_quotacheck(struct session *session,
                     unsigned long *currentp, unsigned long *limitp)
{
    void *old_callback;

    my_quota_active  = NIL;
    my_quota_current = 0;
    my_quota_limit   = 0;
    *currentp = 0;
    *limitp   = 0;

    old_callback = mail_parameters (session->inbox_stream, GET_QUOTA, NIL);
    mail_parameters (session->inbox_stream, SET_QUOTA, my_quotalist_callback);
    if (!imap_getquotaroot(session->inbox_stream, "INBOX")) {
        return(NIL);
    }
    mail_parameters (session->inbox_stream, SET_QUOTA, old_callback);

    if (!my_quota_active)
        return(NIL);

    *currentp = my_quota_current;
    *limitp   = my_quota_limit;
    return(T);
}

/* ====================================================================== */

static char *
mbytes(unsigned long kbytes)
{
    static char buf[64];
    unsigned long whole    = kbytes / 1024;
    unsigned long fraction = ((kbytes % 1024) * 100) / 1024;

    if (fraction > 9)
        sprintf(buf, "%lu.%lu", whole, fraction);
    else
        sprintf(buf, "%lu.0%lu", whole, fraction);

    return(buf);
}

static char *
percent(unsigned long used, unsigned long limit)
{
    static char buf[64], *s;
    int  i, digit;

    if (used >= limit) {
        strcpy(buf, "100.00%");
        return(buf);
    }

    /* Calculate first 4 places of percentage (may have leading zeros) */
    s = buf;
    for (i = 0 ; i < 4 ; i++) {
        used  *= 10;
        digit  = used/limit;
        used  -= (digit*limit);

        *s++ = '0' + digit;
        if (i == 1) *s++ = '.';
    }
    *s++ = '%';
    *s   = '\0';

    /* Trim leading zero in "0x.yz */
    return((buf[0] == '0') ? buf+1 : buf);
}

void cmd_quota(struct session *session)
{
    struct template_vals *tvals = session->template_vals;
    struct request *request = session->request;
    struct buffer *b = request->write_buffer;
    struct account *account = session->account;
    unsigned long current, limit;
 
    if (request->method == POST) {
        session_redirect(session, request, "manage");
        return;
    }

    if (account_check_quota(account, request->pool)) {
        session_message(session, "Quota check operation complete");
    } else {
        char *msg = account_fetch_message(account);

        session_alert(session, "Unable to check quota: %s", msg);
        session_log(session,
                    "[cmd_quota] Unable to check quota: %s", msg);
    }
    template_vals_foreach_init(tvals, "@line", 0);
    template_vals_foreach_string(tvals, "@line", 0, "type", "File Quota");
    template_vals_foreach_ulong(tvals, "@line", 0, "used", account->iused);
    template_vals_foreach_ulong(tvals, "@line", 0, "limit", account->ilimit);
    template_vals_foreach_string(tvals, "@line", 0, "percent",
                                 percent(account->iused, account->ilimit));

    template_vals_foreach_init(tvals, "@line", 1);
    template_vals_foreach_string(tvals, "@line", 1, "type",
                                 "Block Quota (MBytes)");
    template_vals_foreach_string(tvals, "@line", 1, "used",
                                 mbytes(account->bused));
    template_vals_foreach_string(tvals, "@line", 1, "limit", 
                                 mbytes(account->blimit));
    template_vals_foreach_string(tvals, "@line", 1, "percent",
                                 percent(account->bused, account->blimit));

    mailstore_quotacheck(session, &current, &limit);

    template_vals_foreach_init(tvals, "@line", 2);
    template_vals_foreach_string(tvals, "@line", 2, "type",
                                 "Mailstore Quota (MBytes)");
    template_vals_foreach_string(tvals, "@line", 2, "used",
                                 mbytes(current));
    template_vals_foreach_string(tvals, "@line", 2, "limit", 
                                mbytes(limit));
    template_vals_foreach_string(tvals, "@line", 2, "percent",
                                 percent(current, limit));

    session_seed_template(session, tvals);
    template_expand("quota", tvals, b);
    response_html(request, 200);        /* Success */
}
