#!perl
use Cassandane::Tiny;

sub test_permessage_getset
{
    my ($self) = @_;

    xlog $self, "testing getting and setting message scope annotations";

    my $talk = $self->{store}->get_client();

    xlog $self, "Append 3 messages";
    my %msg;
    $msg{A} = $self->make_message('Message A');
    $msg{B} = $self->make_message('Message B');
    $msg{C} = $self->make_message('Message C');

    my $entry = '/comment';
    my $attrib = 'value.priv';
    my $value1 = "Hello World";
    my $value2 = "Goodnight\0Irene";
    my $value3 = "Gump";

    xlog $self, "fetch an annotation - should be no values";
    my $res = $talk->fetch('1:*',
                           ['annotation', [$entry, $attrib]]);
    $self->assert_str_equals('ok', $talk->get_last_completion_response());
    $self->assert_not_null($res);
    $self->assert_deep_equals(
            {
                1 => { annotation => { $entry => { $attrib => undef } } },
                2 => { annotation => { $entry => { $attrib => undef } } },
                3 => { annotation => { $entry => { $attrib => undef } } },
            },
            $res);

    xlog $self, "store an annotation";
    $talk->store('1', 'annotation',
                 [$entry, [$attrib, $value1]]);
    $self->assert_str_equals('ok', $talk->get_last_completion_response());

    xlog $self, "fetch the annotation again, should see changes";
    $res = $talk->fetch('1:*',
                        ['annotation', [$entry, $attrib]]);
    $self->assert_str_equals('ok', $talk->get_last_completion_response());
    $self->assert_not_null($res);
    $self->assert_deep_equals(
            {
                1 => { annotation => { $entry => { $attrib => $value1 } } },
                2 => { annotation => { $entry => { $attrib => undef } } },
                3 => { annotation => { $entry => { $attrib => undef } } },
            },
            $res);

    xlog $self, "store an annotation with an embedded NUL";
    $talk->store('3', 'annotation',
                 [$entry, [$attrib, $value2]]);
    $self->assert_str_equals('ok', $talk->get_last_completion_response());

    xlog $self, "fetch the annotation again, should see changes";
    $res = $talk->fetch('1:*',
                        ['annotation', [$entry, $attrib]]);
    $self->assert_str_equals('ok', $talk->get_last_completion_response());
    $self->assert_not_null($res);
    $self->assert_deep_equals(
            {
                1 => { annotation => { $entry => { $attrib => $value1 } } },
                2 => { annotation => { $entry => { $attrib => undef } } },
                3 => { annotation => { $entry => { $attrib => $value2 } } },
            },
            $res);

    xlog $self, "store multiple annotations";
    # Note $value3 has no whitespace so we have to
    # convince Mail::IMAPTalk to quote it anyway
    $talk->store('1:*', 'annotation',
                 [$entry, [$attrib, { Quote => $value3 }]]);
    $self->assert_str_equals('ok', $talk->get_last_completion_response());

    xlog $self, "fetch the annotation again, should see changes";
    $res = $talk->fetch('1:*',
                        ['annotation', [$entry, $attrib]]);
    $self->assert_str_equals('ok', $talk->get_last_completion_response());
    $self->assert_not_null($res);
    $self->assert_deep_equals(
            {
                1 => { annotation => { $entry => { $attrib => $value3 } } },
                2 => { annotation => { $entry => { $attrib => $value3 } } },
                3 => { annotation => { $entry => { $attrib => $value3 } } },
            },
            $res);

    xlog $self, "delete an annotation";
    # Note $value3 has no whitespace so we have to
    # convince Mail::IMAPTalk to quote it anyway
    $talk->store('2', 'annotation',
                 [$entry, [$attrib, undef]]);
    $self->assert_str_equals('ok', $talk->get_last_completion_response());

    xlog $self, "fetch the annotation again, should see changes";
    $res = $talk->fetch('1:*',
                        ['annotation', [$entry, $attrib]]);
    $self->assert_str_equals('ok', $talk->get_last_completion_response());
    $self->assert_not_null($res);
    $self->assert_deep_equals(
            {
                1 => { annotation => { $entry => { $attrib => $value3 } } },
                2 => { annotation => { $entry => { $attrib => undef } } },
                3 => { annotation => { $entry => { $attrib => $value3 } } },
            },
            $res);

    xlog $self, "delete all annotations";
    # Note $value3 has no whitespace so we have to
    # convince Mail::IMAPTalk to quote it anyway
    $talk->store('1:*', 'annotation',
                 [$entry, [$attrib, undef]]);
    $self->assert_str_equals('ok', $talk->get_last_completion_response());

    xlog $self, "fetch the annotation again, should see changes";
    $res = $talk->fetch('1:*',
                        ['annotation', [$entry, $attrib]]);
    $self->assert_str_equals('ok', $talk->get_last_completion_response());
    $self->assert_not_null($res);
    $self->assert_deep_equals(
            {
                1 => { annotation => { $entry => { $attrib => undef } } },
                2 => { annotation => { $entry => { $attrib => undef } } },
                3 => { annotation => { $entry => { $attrib => undef } } },
            },
            $res);
}
