/* $Cambridge: hermes/src/prayer/cmd/cmd_block.c,v 1.2 2008/05/19 15:55:54 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"

static void
generate_form(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;
    struct list_item *item;
    unsigned long count;
    char *value;

    count = 0;
    for (item = account->block_list->head; item; item = item->next) {
        struct filter *filter = (struct filter *) item;

        if (filter->type != FILTER_BLOCK) {
            count++;
            continue;
        }
        value = pool_printf(tvals->pool, "%s@%s",
                            filter->local_part, filter->domain);

        template_vals_foreach_init(tvals, "@blocks", count);
        template_vals_foreach_ulong(tvals, "@blocks", count, "offset", count);
        template_vals_foreach_string(tvals, "@blocks", count, "value", value);
        count++;
    }

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

static void
generate_error(struct session *session)
{
    struct template_vals *tvals = session->template_vals;
    struct request *request = session->request;
    struct account *account = session->account;
    char *msg = account_fetch_message(account);
    struct buffer *b = request->write_buffer;

    if (!(msg && msg[0]))
        msg = "Unable to check mail processing status";

    template_vals_string(tvals, "msg", msg);

    session_seed_template(session, tvals);
    template_expand("block_fail", tvals, b);
    response_html(request, 200);
}

void
cmd_block(struct session *session)
{
    struct request *request = session->request;
    struct account *account = session->account;
    unsigned long offset;
    struct assoc *h = NIL;
    struct filter *filter;
    char *param;

    if (request->method != POST) {
        if (!account_mail_check(account, request->pool)) {
            generate_error(session);
            return;
        }

        if ((request->argc >= 3) && !strcmp(request->argv[1], "remove")) {
            offset = atoi(request->argv[2]);
            account_block_remove(account, offset);
            if (account_mail_update(account, request->pool)) {
                session_message(session, "Removed block number: %lu",
                                offset + 1);
            } else {
                char *msg = account_fetch_message(account);

                session_message(session,
                                "Failed to remove block number: %lu: %s",
                                offset + 1, msg);
                session_log(session, 
                            "[cmd_block] Failed to remove block number: %lu: %s",
                            offset + 1, msg);
            }

        }
        generate_form(session);
        return;
    }

    filter = filter_alloc();
    request_decode_form(request);
    h = request->form;

    if (assoc_lookup(h, "sub_cancel")) {
        session_redirect(session, request, "manage");
        return;
    }

    param = assoc_lookup(h, "param");

    if (param && param[0])
        param = string_trim_whitespace(param);

    if (!(param && param[0])) {
        session_message(session, "Missing or empty parameter field");
        generate_form(session);
        return;
    }

    /* Param is address or address wildcard */
    if (!filter_test_addr(filter, session, param)) {
        session_message(session, "Invalid filter pattern");
        generate_form(session);
        return;
    }

    /* Block is special: doesn't require target folder */
    filter_set_type(filter, FILTER_BLOCK);
    filter_set_addr(filter, session, param);
    account_block_add(session->account, filter);

    if (account_mail_update(account, request->pool)) {
        session_message(session, "Added BLOCK filter");
    } else {
        char *msg = account_fetch_message(account);

        session_message(session, "Failed to add BLOCK filter: %s", msg);
        session_log(session,
                    "[cmd_block] Failed to add BLOCK filter: %s", msg);
    }

    generate_form(session);
}
