/* $Cambridge: hermes/src/prayer/cmd/cmd_filter.c,v 1.4 2008/09/17 17:20:25 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 *type;
    char *type_strong;
    char *value;

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

        template_vals_foreach_init(tvals, "@filters", count);
        template_vals_foreach_ulong(tvals, "@filters", count, "offset", count);

        switch (filter->type) {
        case FILTER_SENDER:
            type = "sender";
            type_strong = "SENDER";
            value = pool_printf(tvals->pool, "%s@%s",
                                filter->local_part, filter->domain);
            break;
        case FILTER_RECIPIENT:
            type = "recipient";
            type_strong = "RECIPIENT";
            value = pool_printf(tvals->pool, "%s@%s",
                                filter->local_part, filter->domain);
            break;
        case FILTER_SUBJECT:
            type = "subject";
            type_strong = "SUBJECT";
            value = filter->subject;
            break;
        default:
            type = "unknown";
            type_strong = "UNKNOWN";
            value = "";
            break;
        }

        template_vals_foreach_string(tvals, "@filters", count,
                                     "type_strong", type_strong);
        template_vals_foreach_string(tvals, "@filters", count,
                                     "type", type);
        template_vals_foreach_string(tvals, "@filters", count,
                                     "value", value);
        if (filter->mailbox)
            template_vals_foreach_string(tvals, "@filters", count,
                                         "mailbox", filter->mailbox);
        if (filter->copy)
            template_vals_foreach_ulong(tvals, "@filters", count, "copy", 1);
                                        
        count++;
    } 
    session_seed_template(session, tvals);
    template_expand("filter", tvals, b);
    response_html(request, 200);        /* Success */
}

static void
generate_error(struct session *session)
{
    struct template_vals *tvals = session->template_vals;
    struct account *account = session->account;
    struct request *request = session->request;
    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("filter_fail", tvals, b);
    response_html(request, 200);
}

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

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

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

                session_alert(session, "Failed to remove filter number: %lu",
                              offset + 1, msg);
                session_log(session,
                            "[cmd_filter] Failed to remove filter number: %lu",
                            offset + 1, msg);
            }
        }
        generate_form(session);
        return;
    }

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

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

    type = assoc_lookup(h, "type");
    param = assoc_lookup(h, "param");

    if (!(type && type[0])) {
        session_alert(session, "Missing type field");
        generate_form(session);
        return;
    }

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

    if (!strcmp(type, "block") ||
        !strcmp(type, "sender") || !strcmp(type, "recipient")) {
        /* Param is address or address wildcard */
        if (!filter_test_addr(filter, session, param)) {
            session_alert(session, "Invalid filter pattern");
            generate_form(session);
            return;
        }
    }

    if (!strcmp(type, "subject")) {
        session_message(session, "Adding SUBJECT filter: \"%s\"", param);
        filter_set_type(filter, FILTER_SUBJECT);
        filter_set_subject(filter, param);
    } else if (!strcmp(type, "sender")) {
        session_message(session, "Adding SENDER filter: \"%s\"", param);
        filter_set_type(filter, FILTER_SENDER);
        filter_set_addr(filter, session, param);
    } else if (!strcmp(type, "recipient")) {
        session_message(session, "Adding RECIPIENT filter: \"%s\"",
                        param);
        filter_set_type(filter, FILTER_RECIPIENT);
        filter_set_addr(filter, session, param);
    } else {
        session_alert(session, "Bad/Unknown filter type");
        session_redirect(session, request, "error");
        return;
    }
    
    session->half_filter = filter;
    session_redirect(session, request, "filter_select");
}
