#!perl
use Cassandane::Tiny;
use Cwd qw(abs_path);

sub test_restore_mail_no_annotator
    :NoStartInstances
    ($self)
{
    $self->config_set(annotation_callout =>
                      '@basedir@/conf/socket/annotator.sock');

    $self->{instance}->add_generic_listener(
        name => 'annotator',
        port => $self->{instance}->{config}->get('annotation_callout'),
        argv => sub {
            my ($listener) = @_;
            return (
                abs_path('utils/annotator.pl'),
                '--port', $listener->port(),
                '--pidfile', '@basedir@/run/annotator.pid',
                );
        });

    $self->_start_instances();
    $self->_setup_http_service_objects();

    my $jmap = $self->{jmap};

    $jmap->DefaultUsing([
        'urn:ietf:params:jmap:core',
        'urn:ietf:params:jmap:mail',
        'https://cyrusimap.org/ns/jmap/backup',
    ]);

    xlog "create email in Inbox";
    my $res = $jmap->CallMethods([
        ['Mailbox/get', {
         }, "R1"]
    ]);

    $self->assert_num_equals(1, scalar(@{$res->[0][1]{list}}));
    my $inboxId = $res->[0][1]{list}[0]{id};

    my $flag = '$X-ME-Annot-2';

    $res = $jmap->CallMethods([
        ['Email/set', {
            create => {
                email1 => {
                    mailboxIds => {
                        $inboxId => JSON::true
                    },
                    from => [{ email => q{foo1@bar} }],
                    to => [{ email => q{bar1@foo} }],
                    subject => "email1",
                    textBody => [{ partId => '1' }],
                    bodyValues => { 1 => { value => "set_flag $flag\r\n" }}
                }
            },
        }, 'R2'],
        ['Email/get', {
            ids => [ '#email1' ],
            properties => ['receivedAt', 'keywords']
         }, "R3"]
    ]);
    my $emailId1 = $res->[0][1]{created}{email1}{id};
    $self->assert_not_null($emailId1);
    my $emailAt1 = $res->[1][1]{list}[0]{receivedAt};

    xlog "check that annotator added flag";
    $self->assert_equals(JSON::true,
                         $res->[1][1]{list}[0]{keywords}{'$x-me-annot-2'});

    xlog "create new mailbox";
    $res = $jmap->CallMethods([
        ['Mailbox/set', {
            create => {
                "1" => {
                    name => "foo"
                }
            }
         }, "R4"],
    ]);
    $self->assert_not_null($res);
    my $fooId = $res->[0][1]{created}{"1"}{id};
    $self->assert_not_null($fooId);

    xlog "move email from Inbox to foo";
    $res = $jmap->CallMethods([
        ['Email/set', {
            update => { $emailId1 => {
                "mailboxIds/$inboxId" => undef,
                "mailboxIds/$fooId" => JSON::true,
                keywords => undef    
                } }
         }, "R5"],
        ['Email/get', {
            ids => [ $emailId1 ],
            properties => ['keywords']
         }, "R3"]
    ]);

    xlog "check that flag was removed";
    $self->assert_null($res->[1][1]{list}[0]{keywords}{'$x-me-annot-2'});

    my $mark = time();
    sleep 2;

    xlog "destroy 'foo' mailbox";
    $res = $jmap->CallMethods([
        ['Mailbox/set', {
            destroy => ["$fooId"],
            onDestroyRemoveEmails => JSON::true
         }, "R6"],
    ]);
    $self->assert_num_equals(1, scalar(@{$res->[0][1]{destroyed}}));
    $self->assert_str_equals($fooId, $res->[0][1]{destroyed}[0]);

    my $diff = time() - $mark;
    my $period = "PT" . $diff . "S";

    xlog "restore mail prior to most recent changes";
    $res = $jmap->CallMethods([
        ['Backup/restoreMail', {
            restoreDrafts => JSON::false,
            restoreNonDrafts => JSON::true,
            undoPeriod => $period
         }, "R7"],
        ['Mailbox/get', {
         }, "R8"],
        ['Email/get', {
            ids => ["$emailId1"],
            properties => ['subject', 'keywords', 'mailboxIds', 'receivedAt']
         }, "R9"]
    ]);
    $self->assert_not_null($res);
    $self->assert_num_equals(0, $res->[0][1]{numDraftsRestored});
    $self->assert_num_equals(1, $res->[0][1]{numNonDraftsRestored});

    $self->assert_num_equals(2, scalar(@{$res->[1][1]{list}}));
    $self->assert_str_equals("foo", $res->[1][1]{list}[1]{name});
    my $newFooId = $res->[1][1]{list}[1]{id};

    $self->assert_num_equals(1, scalar(@{$res->[2][1]{list}}));
    $self->assert_str_equals("$emailId1", $res->[2][1]{list}[0]{id});
    $self->assert_str_equals("$emailAt1", $res->[2][1]{list}[0]{receivedAt});
    $self->assert_equals(JSON::true, $res->[2][1]{list}[0]{keywords}->{'$restored'});
    $self->assert_equals(JSON::true, $res->[2][1]{list}[0]{mailboxIds}{$newFooId});
    $self->assert_null($res->[2][1]{list}[0]{mailboxIds}->{$inboxId});

    xlog "check that annotator DID NOT add flag";
    $self->assert_null($res->[2][1]{list}[0]{keywords}{'$x-me-annot-2'});
}
