/* $Cambridge: hermes/src/prayer/cmd/cmd_abook_search.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 int abook_search_field_form_to_enum(char *key)
{
    int field = ABOOK_SEARCH_FIELD_NONE;

    if (!strcmp(key, "alias"))
        field = ABOOK_SEARCH_FIELD_ALIAS;
    else if (!strcmp(key, "name"))
        field = ABOOK_SEARCH_FIELD_NAME;
    else if (!strcmp(key, "comment"))
        field = ABOOK_SEARCH_FIELD_COMMENT;
    else if (!strcmp(key, "email"))
        field = ABOOK_SEARCH_FIELD_EMAIL;

    return (field);
}

static int abook_search_type_form_to_enum(char *op)
{
    int type = ABOOK_SEARCH_TYPE_NONE;

    if (!strcmp(op, "is"))
        type = ABOOK_SEARCH_TYPE_IS;
    else if (!strcmp(op, "begins"))
        type = ABOOK_SEARCH_TYPE_BEGINS;
    else if (!strcmp(op, "ends"))
        type = ABOOK_SEARCH_TYPE_ENDS;
    else if (!strcmp(op, "contains"))
        type = ABOOK_SEARCH_TYPE_CONTAINS;

    return (type);
}

static void
generate_form(struct session *session, struct abook_search_list *asl,
              BOOL do_search)
{
    struct template_vals *tvals = session->template_vals;
    struct request *request = session->request;
    struct buffer *b = request->write_buffer;
    struct options *options = session->options;
    struct abook *abook = options->abook;
    unsigned long i, count;
    struct abook_search_elt *ase;
    struct abook_entry *abe;
    char *field, *type;

    if (asl->match_all)
        template_vals_ulong(tvals, "$match_all", 1);

    for (i = 0, ase = asl->first; ase; ase = ase->next, i++) {
        template_vals_foreach_init(tvals, "@filters", i);
        template_vals_foreach_ulong(tvals, "@filters", i,
                                    "count", i);
        template_vals_foreach_string(tvals, "@filters", i,
                                     "value", ase->value);

        switch (ase->field) {
        case ABOOK_SEARCH_FIELD_NONE:
            field = "name";
            break;
        case ABOOK_SEARCH_FIELD_ALIAS:
            field = "alias";
            break;
        case ABOOK_SEARCH_FIELD_NAME:
        default:
            field = "name";
            break;
        case ABOOK_SEARCH_FIELD_COMMENT:
            field = "comment";
            break;
        case ABOOK_SEARCH_FIELD_EMAIL:
            field = "email";
            break;
        }
        template_vals_foreach_string(tvals, "@filters", i,
                                     "selected", field);
        switch (ase->type) {
        case ABOOK_SEARCH_TYPE_NONE:
            type = "contains";
            break;
        case ABOOK_SEARCH_TYPE_IS: 
            type = "is";
            break;
        case ABOOK_SEARCH_TYPE_BEGINS:
            type = "begins";
            break;
        case ABOOK_SEARCH_TYPE_ENDS:
            type = "ends";
            break;
        case ABOOK_SEARCH_TYPE_CONTAINS:
        default:
            type = "contains";
            break;
        }
        template_vals_foreach_string(tvals, "@filters", i,
                                     "type", type);
    }

    if (do_search) {
        abook_search_init(abook);
        count = 0;
        while (abook_search_find_next(abook, asl))
            count++;

        template_vals_ulong(tvals, "$count", count);

        abook_search_init(abook);
        i = 0;
        while ((abe = abook_search_find_next(abook, asl))) {
            template_vals_foreach_init(tvals, "@results", i);
            template_vals_foreach_string(tvals, "@results", i,
                                         "alias", abe->alias);
            template_vals_foreach_string(tvals, "@results", i,
                                         "name", abe->name);
            template_vals_foreach_string(tvals, "@results", i,
                                         "comment", abe->comment);
            template_vals_foreach_string(tvals, "@results", i,
                                         "email", abe->email);
            i++;
        }
    }
    session_seed_template(session, tvals);
    template_expand("abook_search", tvals, b);
    response_html(request, 200);
}

void cmd_abook_search(struct session *session)
{
    struct request *request = session->request;
    struct assoc *h = NIL;
    unsigned long i;
    char *key, *op, *value, *s, *t;
    int field, type;
    struct abook_search_list *asl;

    if (request->method == POST) {
        request_decode_form(request);
        h = request->form;
    }

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

    if ((s = assoc_lookup(h, "cond")) && !strcmp(s, "all"))
        asl = abook_search_list_create(T);
    else
        asl = abook_search_list_create(NIL);

    for (i = 0; 1; i++) {
        t = string_itoa(request->pool, i);

        s = pool_strcat(request->pool, "key", t);
        if ((key = assoc_lookup(h, s)) == NIL)
            break;

        s = pool_strcat(request->pool, "op", t);
        if ((op = assoc_lookup(h, s)) == NIL)
            break;

        s = pool_strcat(request->pool, "val", t);
        if ((value = assoc_lookup(h, s)) == NIL)
            break;

        field = abook_search_field_form_to_enum(key);
        type = abook_search_type_form_to_enum(op);

        if ((field == ABOOK_SEARCH_FIELD_NONE)
            || (type == ABOOK_SEARCH_TYPE_NONE))
            break;

        abook_search_list_add(asl, field, type, value);
    }

    /* Add new (empty) filter to end of list if empty or additional requested */
    if (!asl->first || assoc_lookup(h, "sub_add_cond"))
        abook_search_list_add(asl,
                              ABOOK_SEARCH_FIELD_NAME,
                              ABOOK_SEARCH_TYPE_CONTAINS, "");

    generate_form(session, asl, (request->method == POST) ? T : NIL);

    abook_search_list_free(asl);
}
