zrequire('unread');
zrequire('unread_ops');
zrequire('message_flags');

set_global('ui', {});
set_global('channel', {});
set_global('starred_messages', {
    add: () => {},
    remove: () => {},
});

run_test('starred', () => {
    const message = {
        id: 50,
    };
    set_global('current_msg_list', {
        all_messages: () => [message],
        is_search: () => false,
    });
    let ui_updated;

    ui.update_starred_view = () => {
        ui_updated = true;
    };

    let posted_data;

    channel.post = (opts) => {
        assert.equal(opts.url, '/json/messages/flags');
        posted_data = opts.data;
    };

    message_flags.toggle_starred_and_update_server(message);

    assert(ui_updated);

    assert.deepEqual(posted_data, {
        messages: '[50]',
        flag: 'starred',
        op: 'add',
    });

    assert.deepEqual(message, {
        id: 50,
        starred: true,
    });

    ui_updated = false;

    message_flags.toggle_starred_and_update_server(message);

    assert(ui_updated);

    assert.deepEqual(posted_data, {
        messages: '[50]',
        flag: 'starred',
        op: 'remove',
    });

    assert.deepEqual(message, {
        id: 50,
        starred: false,
    });
});
run_test('read', () => {
    // Way to capture posted info in every request
    let channel_post_opts;
    channel.post = (opts) => {
        channel_post_opts = opts;
    };

    // For testing purpose limit the batch size value to 5 instead of 1000
    message_flags._unread_batch_size = 5;
    let msgs_to_flag_read = [
        { locally_echoed: false, id: 1 },
        { locally_echoed: false, id: 2 },
        { locally_echoed: false, id: 3 },
        { locally_echoed: false, id: 4 },
        { locally_echoed: false, id: 5 },
        { locally_echoed: false, id: 6 },
        { locally_echoed: false, id: 7 },
    ];
    message_flags.send_read(msgs_to_flag_read);
    assert.deepEqual(channel_post_opts, {
        url: '/json/messages/flags',
        idempotent: true,
        data: {
            messages: '[1,2,3,4,5]',
            op: 'add',
            flag: 'read',
        },
        success: channel_post_opts.success,
    });

    // Mock successful flagging of ids
    let success_response_data = {
        messages: [1, 2, 3, 4, 5],
    };
    channel_post_opts.success(success_response_data);
    assert.deepEqual(channel_post_opts, {
        url: '/json/messages/flags',
        idempotent: true,
        data: {
            messages: '[6,7]',
            op: 'add',
            flag: 'read',
        },
        success: channel_post_opts.success,
    });
    success_response_data = {
        messages: [6, 7],
    };
    channel_post_opts.success(success_response_data);

    // Don't flag locally echoed messages as read
    const local_msg_1 = { locally_echoed: true, id: 1 };
    const local_msg_2 = { locally_echoed: true, id: 2 };
    msgs_to_flag_read = [
        local_msg_1,
        local_msg_2,
        { locally_echoed: false, id: 3 },
        { locally_echoed: false, id: 4 },
        { locally_echoed: false, id: 5 },
        { locally_echoed: false, id: 6 },
        { locally_echoed: false, id: 7 },
    ];
    message_flags.send_read(msgs_to_flag_read);
    assert.deepEqual(channel_post_opts, {
        url: '/json/messages/flags',
        idempotent: true,
        data: {
            messages: '[3,4,5,6,7]',
            op: 'add',
            flag: 'read',
        },
        success: channel_post_opts.success,
    });

    // Mark them non local
    local_msg_1.locally_echoed = false;
    local_msg_2.locally_echoed = false;

    // Mock successful flagging of ids
    success_response_data = {
        messages: [3, 4, 5, 6, 7],
    };
    channel_post_opts.success(success_response_data);

    // Former locally echoed messages flagging retried
    assert.deepEqual(channel_post_opts, {
        url: '/json/messages/flags',
        idempotent: true,
        data: {
            messages: '[1,2]',
            op: 'add',
            flag: 'read',
        },
        success: channel_post_opts.success,
    });
});
