#!perl
use Cassandane::Tiny;

sub test_email_query_fromcontactgroupid_when_shared_addrbook_exists
    :needs_component_sieve :MagicPlus :NoAltNameSpace
    :JMAPExtensions
    ($self)
{
    my $jmap = $self->{jmap};

    my $admintalk = $self->{adminstore}->get_client();
    $admintalk->create("user.cassandane.#addressbooks.Addrbook1",
                       ['TYPE', 'ADDRESSBOOK']) or die;
    $admintalk->create("user.cassandane.#addressbooks.Addrbook2",
                       ['TYPE', 'ADDRESSBOOK']) or die;

    xlog "Create shared addressbook";
    $admintalk->create("user.other");
    $admintalk->create("user.other.#addressbooks.Shared",
                       ['TYPE', 'ADDRESSBOOK']);
    $admintalk->setacl("user.other.#addressbooks.Shared",
                       "cassandane", "lrswipkxtecdn") or die;

    my $imap = $self->{store}->get_client(NoLogin => 1);
    $imap->login("cassandane+dav", "secret");
    my $subscribe_res = $imap->subscribe("user.other.#addressbooks.Shared");
    $self->assert_str_equals("ok", $subscribe_res);

    my $using = [
        'urn:ietf:params:jmap:core',
        'urn:ietf:params:jmap:mail',
        'https://cyrusimap.org/ns/jmap/mail',
        'https://cyrusimap.org/ns/jmap/contacts',
    ];

    xlog "Create a shared contact, necessary to trigger bug";
    my $http = $self->{instance}->get_service("http");
    my $other_user = $self->{instance}->create_user_without_setup('other');
    my $otherJmap = $other_user->new_jmaptester;

    xlog "Create contact in shared addressbook";
    my $res = $otherJmap->CallMethods([
        ['Contact/set', {
            create => {
                sharedContact => {
                    emails => [{
                        type => 'personal',
                        value => 'sharedcontact@local',
                    }],
                    addressbookId => 'Shared',
                },
            },
        }, 'R1'],
    ], $using);
    $self->assert_not_null($res->[0][1]{created}{sharedContact}{id});

    $res = $jmap->CallMethods([
        ['Contact/set', {
            create => {
                contact1 => {
                    emails => [{
                        type => 'personal',
                        value => 'contact1@local',
                    }],
                },
                contact2 => {
                    emails => [{
                        type => 'personal',
                        value => 'contact2@local',
                    }],
                },
            }
        }, 'R1'],
        ['ContactGroup/set', {
            create => {
                contactGroup1 => {
                    name => 'contactGroup1',
                    contactIds => ['#contact1'],
                    addressbookId => 'Addrbook1',
                },
            }
        }, 'R2'],
    ], $using);

    my $contactId1 = $res->[0][1]{created}{contact1}{id};
    $self->assert_not_null($contactId1);
    my $contactId2 = $res->[0][1]{created}{contact2}{id};
    $self->assert_not_null($contactId2);
    my $contactGroupId1 = $res->[1][1]{created}{contactGroup1}{id};
    $self->assert_not_null($contactGroupId1);

    $self->make_message("msg1", from => Cassandane::Address->new(
        localpart => 'contact1', domain => 'local'
    )) or die;
    $self->make_message("msg2", from => Cassandane::Address->new(
        localpart => 'contact2', domain => 'local'
    )) or die;
    $self->make_message("msg3", from => Cassandane::Address->new(
        localpart => 'neither', domain => 'local'
    )) or die;
    $self->{instance}->run_command({cyrus => 1}, 'squatter');

    $res = $jmap->CallMethods([
        ['Email/query', {
            sort => [{ property => "subject" }],
        }, 'R1']
    ], $using);

    $self->assert_num_equals(3, scalar @{$res->[0][1]{ids}});
    my $emailId1 = $res->[0][1]{ids}[0];

    # Filter by contact group.
    $res = $jmap->CallMethods([
        ['Email/query', {
            filter => {
                fromContactGroupId => $contactGroupId1
            },
            sort => [
                { property => "subject" }
            ],
        }, 'R1']
    ], $using);
    $self->assert_num_equals(1, scalar @{$res->[0][1]{ids}});
    $self->assert_str_equals($emailId1, $res->[0][1]{ids}[0]);
}
