/* $Cambridge: hermes/src/prayer/cmd/cmd_aggregate.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 BOOL
aggregate_delete(struct session *session, char *sequence,
                 unsigned long count)
{
    MAILSTREAM *stream = session->stream;

    if (!ml_flag(session, stream, sequence, "\\DELETED", ST_SET)) {
        session_alert(session, "Failed to delete messages: %s",
                      ml_errmsg());
        session_log(session,
                    "[cmd_aggregate] Failed to delete messages: %s",
                    ml_errmsg());
        return (NIL);
    }

    if (count > 1) {
        session_message(session, "Deleted %lu messages", count);
        session_log(session,
                    "[cmd_aggregate] Deleted %lu messages from %s",
                    count, session->foldername);
    } else {
        session_message(session, "Deleted 1 message");
        session_log(session, "[cmd_aggregate] Deleted 1 message from %s",
                    session->foldername);
    }
    return (T);
}

static BOOL
aggregate_undelete(struct session *session,
                   char *sequence, unsigned long count)
{
    MAILSTREAM *stream = session->stream;

    if (!ml_flag(session, stream, sequence, "\\DELETED", 0)) {
        session_alert(session, "Failed to undelete messages: %s",
                      ml_errmsg());
        session_log(session,
                    "[cmd_aggregate] Failed to undelete messages: %s",
                    ml_errmsg());
        return (NIL);
    }

    if (count > 1) {
        session_message(session, "Undeleted %lu messages", count);
        session_log(session,
                    "[cmd_aggregate] Undeleted %lu messages from %s",
                    count, session->foldername);
    } else {
        session_message(session, "Undeleted 1 message");
        session_log(session,
                    "[cmd_aggregate] Undeleted 1 message from %s",
                    session->foldername);
    }
    return (T);
}

static BOOL
aggregate_read(struct session *session, char *sequence,
               unsigned long count)
{
    MAILSTREAM *stream = session->stream;

    if (!ml_flag(session, stream, sequence, "\\SEEN", ST_SET)) {
        session_alert(session,
                      "Failed to flag messages as read: %s",
                      ml_errmsg());
        session_log(session,
                    "[cmd_aggregate] Failed to flag messages as read: %s",
                    ml_errmsg());
        return (NIL);
    }

    if (count > 1) {
        session_message(session, "Flagged %lu messages as read", count);
        session_log(session,
                    "[cmd_aggregate] Flagged %lu messages as read from %s",
                    count, session->foldername);
    } else {
        session_message(session, "Flagged 1 message as read");
        session_log(session,
                    "[cmd_aggregate] Flagged 1 message as read from %s",
                    session->foldername);
    }
    return (T);
}

static BOOL
aggregate_unread(struct session *session, char *sequence,
                 unsigned long count)
{
    MAILSTREAM *stream = session->stream;

    if (!ml_flag(session, stream, sequence, "\\SEEN", 0)) {
        session_alert(session,
                      "Failed to flag messages as unread: %s",
                      ml_errmsg());
        session_log(session,
                    "[cmd_aggregate] Failed to flag messages as unread: %s",
                    ml_errmsg());
        return (NIL);
    }

    if (count > 1) {
        session_message(session, "Flagged %lu messages as unread", count);
        session_log(session,
                    "[cmd_aggregate] Flagged %lu messages as unread from %s",
                    count, session->foldername);
    } else {
        session_message(session, "Flagged 1 message as unread");
        session_log(session,
                    "[cmd_aggregate] Flagged 1 message as unread from %s",
                    session->foldername);
    }
    return (T);
}

void cmd_aggregate(struct session *session)
{
    struct options *options = session->options;
    struct prefs *prefs = options->prefs;
    struct request *request = session->request;
    char *cmd;
    char *sequence;
    BOOL rc;
    unsigned long count;

    request_decode_form(request);

    if (assoc_lookup(request->form, "sub_aggregate"))
        cmd = assoc_lookup(request->form, "aggregate");
    else if (assoc_lookup(request->form, "sub_aggregate2"))
        cmd = assoc_lookup(request->form, "aggregate2");
    else {
        char *pstr = assoc_lookup(request->form, "page");
        unsigned long page = pstr ? atoi(pstr) : 0;
        unsigned long size = msgmap_size(session->zm);
        unsigned long pages = (size / prefs->msgs_per_page) + 1;

        if ((page > 0) && (page <= pages)) {
            session->current
                =
                msgmap_value(session->zm,
                             ((page - 1) * prefs->msgs_per_page) + 1);
            session_message(session, "Switched to page: %lu", page);
        } else
            session_message(session, "Page out of range");
        session_redirect(session, request, "list");
        return;
    }

    if (!(cmd && cmd[0])) {
        session_alert(session, "Invalid form input");
        session_log(session, "[cmd_aggregate] Invalid form input");
        session_redirect(session, request, "list");
        return;
    }

    if (msgmap_marked_count(session->zm) == 0) {
        session_message(session, "No messages marked");
        session_redirect(session, request, "list");
        return;
    }

    if (!strcmp(cmd, "copy")) {
        session_redirect(session, request, "copy/aggregate");
        return;
    } else if (!strcmp(cmd, "forward")) {
        session_redirect(session, request, "forward/aggregate");
        return;
    }

    sequence = msgmap_mark_sequence(session->zm);
    count = msgmap_marked_count(session->zm);

    if (!strcmp(cmd, "delete"))
        rc = aggregate_delete(session, sequence, count);
    else if (!strcmp(cmd, "undelete"))
        rc = aggregate_undelete(session, sequence, count);
    else if (!strcmp(cmd, "read"))
        rc = aggregate_read(session, sequence, count);
    else if (!strcmp(cmd, "unread"))
        rc = aggregate_unread(session, sequence, count);
    else {
        session_alert(session, "Unknown action");
        rc = T;
    }

    if (rc && prefs->use_agg_unmark)
        msgmap_unmark_all(session->zm);

    session_redirect(session, request, (rc) ? "list" : "restart");
}
