#!perl
use Cassandane::Tiny;

sub test_rename_deepfolder_intermediates_rightnow
    :AllowMoves :Replication :min_version_3_3
    :JMAPExtensions :RightNow
    :needs_component_replication
{
    my ($self) = @_;

    my $admintalk = $self->{adminstore}->get_client();

    $admintalk->setquota('user.cassandane', ['STORAGE', 500000]);

    my $rhttp = $self->{replica}->get_service('http');
    my $rjmap = Mail::JMAPTalk->new(
        user => 'cassandane',
        password => 'pass',
        host => $rhttp->host(),
        port => $rhttp->port(),
        scheme => 'http',
        url => '/jmap/',
    );

    my $synclogfname = "$self->{instance}->{basedir}/conf/sync/log";

    $self->_fmjmap_ok('Calendar/set',
        create => {
            "1" => { name => "A calendar" },
        },
    );

    $self->_fmjmap_ok('Contact/set',
        create => {
            "1" => {firstName => "first", lastName => "last"},
            "2" => {firstName => "second", lastName => "last"},
        },
    );

    $self->_fmjmap_ok('Mailbox/set',
        create => {
            "1" => { name => 'Archive', parentId => undef, role => 'archive' },
            "2" => { name => 'Drafts', parentId => undef, role => 'drafts' },
            "3" => { name => 'Junk', parentId => undef, role => 'junk' },
            "4" => { name => 'Sent', parentId => undef, role => 'sent' },
            "5" => { name => 'Trash', parentId => undef, role => 'trash' },
            "6" => { name => 'bar', parentId => undef, role => undef },
            "7" => { name => 'sub', parentId => "#6", role => undef },
        },
    );

    xlog $self, "Create a folder with intermediates";
    $admintalk->create("user.cassandane.folderA.folderB.folderC");

    my $data = $self->_fmjmap_ok('Mailbox/get', properties => ['name']);
    my %byname = map { $_->{name} => $_->{id} } @{$data->{list}};

    xlog $self, "Test replication";
    # replicate and check initial state
    $self->check_replication('cassandane');

    $data = $self->_fmjmap_ok('Mailbox/get', jmap => $rjmap, properties => ['name']);
    my %byname_repl = map { $_->{name} => $_->{id} } @{$data->{list}};

    $self->assert_deep_equals(\%byname, \%byname_repl);

    # n.b. run_replication dropped all our store connections...
    $admintalk = $self->{adminstore}->get_client();
    $self->{instance}->getsyslog();
    my $res = $admintalk->rename('user.cassandane.folderA', 'user.cassandane.folderZ');
    $self->assert(not $admintalk->get_last_error());

    xlog $self, "Make sure we didn't create intermediates in the process!";
    my $syslog = join "\n", $self->{instance}->getsyslog();
    $self->assert_does_not_match(qr/creating intermediate with children/,
                                 $syslog);
    $self->assert_does_not_match(qr/deleting intermediate with no children/,
                                 $syslog);

    $data = $self->_fmjmap_ok('Mailbox/get', properties => ['name']);
    my %byname_new = map { $_->{name} => $_->{id} } @{$data->{list}};

    # we renamed a folder!
    $byname{folderZ} = delete $byname{folderA};

    $self->assert_deep_equals(\%byname, \%byname_new);

    # replicate and check the renames
    $syslog = join "\n", $self->{replica}->getsyslog();

    $self->assert_does_not_match(qr/creating intermediate with children/,
                                 $syslog);
    $self->assert_does_not_match(qr/deleting intermediate with no children/,
                                 $syslog);

    # check replication is clean
    $self->check_replication('cassandane');

    $data = $self->_fmjmap_ok('Mailbox/get', jmap => $rjmap, properties => ['name']);
    my %byname_newrepl = map { $_->{name} => $_->{id} } @{$data->{list}};

    $self->assert_deep_equals(\%byname, \%byname_newrepl);

    # n.b. run_replication dropped all our store connections...
    $admintalk = $self->{adminstore}->get_client();
    $admintalk->delete("user.cassandane");

    xlog $self, "Make sure we didn't create intermediates in the process!";
    $syslog = join "\n", $self->{instance}->getsyslog();
    $self->assert_does_not_match(qr/creating intermediate with children/,
                                 $syslog);
    $self->assert_does_not_match(qr/deleting intermediate with no children/,
                                 $syslog);

    xlog $self, "Make sure there are no files left with cassandane in the name";
    $self->assert_str_equals(q{}, join(q{ }, glob "$self->{instance}{basedir}/conf/user/c/cassandane.*"));
    $self->assert_not_file_test("$self->{instance}{basedir}/data/c/user/cassandane", "-d");
    $self->assert_not_file_test("$self->{instance}{basedir}/conf/quota/c/user.cassandane", "-d");

    # replicate and check the renames
    $syslog = join "\n", $self->{replica}->getsyslog();
    $self->assert_does_not_match(qr/creating intermediate with children/,
                                 $syslog);
    $self->assert_does_not_match(qr/deleting intermediate with no children/,
                                 $syslog);

    xlog $self, "Make sure there are no files left with cassandane in the on the replica";
    $self->assert_str_equals(q{}, join(q{ }, glob "$self->{replica}{basedir}/conf/user/c/cassandane.*"));
    $self->assert_not_file_test("$self->{replica}{basedir}/data/c/user/cassandane", "-d");
    $self->assert_not_file_test("$self->{replica}{basedir}/conf/quota/c/user.cassandane", "-f");

    xlog $self, "Now clean up all the deleted mailboxes";
    $self->{instance}->run_command({ cyrus => 1 }, 'cyr_expire', '-D' => '0', '-a' );
}
