#!perl
use Cassandane::Tiny;

sub test_email_get_calendarevents_itip_schedprops
    :min_version_3_5 :needs_component_jmap :JMAPExtensions
{
    my ($self) = @_;
    my $jmap = $self->{jmap};
    my $imap = $self->{store}->get_client();
    my ($maj, $min) = Cassandane::Instance->get_version();

    # we need 'https://cyrusimap.org/ns/jmap/mail' capability for
    # calendarEvents property
    my @using = @{ $jmap->DefaultUsing() };
    push @using, 'https://cyrusimap.org/ns/jmap/mail';
    $jmap->DefaultUsing(\@using);

    my @testCases = ({
        ical => <<'EOF',
BEGIN:VCALENDAR
PRODID:-//Google Inc//Google Calendar 70.9054//EN
VERSION:2.0
CALSCALE:GREGORIAN
METHOD:REPLY
BEGIN:VEVENT
DTSTART:20210807T130000Z
DTEND:20210807T140000Z
DTSTAMP:20210802T032234Z
ORGANIZER;CN=Test User:mailto:organizer@local
UID:a4294f2a-cafb-407b-951b-67684ed0ba54
ATTENDEE;CUTYPE=INDIVIDUAL;ROLE=REQ-PARTICIPANT;PARTSTAT=TENTATIVE;
 X-NUM-GUESTS=0;X-RESPONSE-COMMENT="Hello\, World!":mailto:attendee@local
CREATED:20210802T032207Z
DESCRIPTION:
LAST-MODIFIED:20210802T032234Z
LOCATION:
SEQUENCE:3
STATUS:CONFIRMED
SUMMARY:iTIP REPLY
TRANSP:OPAQUE
END:VEVENT
END:VCALENDAR
EOF
        wantMethod => 'reply',
        wantScheduleUpdated => '2021-08-02T03:22:34Z',
        wantScheduleSequence => 3,
        wantParticipationComment => 'Hello, World!',
    }, {
        ical => <<'EOF',
BEGIN:VCALENDAR
METHOD:REPLY
PRODID:Microsoft Exchange Server 2010
VERSION:2.0
BEGIN:VTIMEZONE
TZID:Greenwich Standard Time
BEGIN:STANDARD
DTSTART:16010101T000000
TZOFFSETFROM:+0000
TZOFFSETTO:+0000
END:STANDARD
BEGIN:DAYLIGHT
DTSTART:16010101T000000
TZOFFSETFROM:+0000
TZOFFSETTO:+0000
END:DAYLIGHT
END:VTIMEZONE
BEGIN:VEVENT
ATTENDEE;PARTSTAT=ACCEPTED;CN=Opera Tester:mailto:attendee@local
COMMENT;LANGUAGE=en-GB:A comment.\n
UID:a4294f2a-cafb-407b-951b-67684ed0ab56
SUMMARY;LANGUAGE=en-GB:Accepted: iTIP REPLY test
DTSTART;TZID=Greenwich Standard Time:20210807T090000
DTEND;TZID=Greenwich Standard Time:20210807T100000
CLASS:PUBLIC
PRIORITY:5
DTSTAMP:20210802T032446Z
TRANSP:OPAQUE
STATUS:CONFIRMED
SEQUENCE:5
X-MICROSOFT-CDO-APPT-SEQUENCE:1
X-MICROSOFT-CDO-OWNERAPPTID:0
X-MICROSOFT-CDO-BUSYSTATUS:BUSY
X-MICROSOFT-CDO-INTENDEDSTATUS:BUSY
X-MICROSOFT-CDO-ALLDAYEVENT:FALSE
X-MICROSOFT-CDO-IMPORTANCE:1
X-MICROSOFT-CDO-INSTTYPE:0
X-MICROSOFT-DONOTFORWARDMEETING:FALSE
X-MICROSOFT-DISALLOW-COUNTER:FALSE
END:VEVENT
END:VCALENDAR
EOF
        wantMethod => 'reply',
        wantScheduleUpdated => '2021-08-02T03:24:46Z',
        wantScheduleSequence => 5,
        wantParticipationComment => "A comment.\n",
    }, {
        ical => <<'EOF',
BEGIN:VCALENDAR
PRODID:-//Google Inc//Google Calendar 70.9054//EN
VERSION:2.0
CALSCALE:GREGORIAN
METHOD:COUNTER
BEGIN:VEVENT
DTSTART:20210807T130000Z
DTEND:20210807T140000Z
DTSTAMP:20210802T032234Z
ORGANIZER;CN=Test User:mailto:organizer@local
UID:a4294f2a-cafb-407b-951b-67684ed0ba54
ATTENDEE;CUTYPE=INDIVIDUAL;ROLE=REQ-PARTICIPANT;PARTSTAT=TENTATIVE;
 X-NUM-GUESTS=0:mailto:attendee@local
COMMENT:A counter comment
CREATED:20210802T032207Z
DESCRIPTION:
LAST-MODIFIED:20210802T032234Z
LOCATION:
SEQUENCE:3
STATUS:CONFIRMED
SUMMARY:iTIP COUNTER
TRANSP:OPAQUE
END:VEVENT
END:VCALENDAR
EOF
        sinceVersion => ['3','7'],
        wantMethod => 'counter',
        wantScheduleUpdated => '2021-08-02T03:22:34Z',
        wantScheduleSequence => 3,
        wantParticipationComment => 'A counter comment',
    });

    foreach my $i (0 .. $#testCases) {
        my $tc = $testCases[$i];

        # skip tests for older Cyrus versions
        next if $tc->{sinceVersion} &&
            ($maj le $tc->{sinceVersion}[0] ||
            ($maj eq $tc->{sinceVersion}[0] &&
                $min le $tc->{sinceVersion}[1]));

        $tc->{ical} =~ s/\r?\n/\r\n/gs;
        $self->make_message("test$i",
            mime_type => 'multipart/related',
            mime_boundary => 'boundary',
            body => ""
            . "\r\n--boundary\r\n"
            . "Content-Type: text/plain\r\n"
            . "\r\n"
            . "test"
            . "\r\n--boundary\r\n"
            . "Content-Type: text/calendar;charset=utf-8\r\n"
            . "\r\n"
            . $tc->{ical}
            . "\r\n--boundary--\r\n"
        ) || die;
        $self->{instance}->run_command({cyrus => 1}, 'squatter', '-i');
        my $res = $jmap->CallMethods([
            ['Email/query', {
                sort => [{
                    property => 'subject',
                    isAscending => JSON::false,
                }],
                limit => 1,
            }, "R1"],
            ['Email/get', {
                '#ids' => {
                    resultOf => 'R1',
                    name => 'Email/query',
                    path => '/ids'
                },
                properties => ['calendarEvents'],
            }, 'R2' ],
        ]);

        my $event = (values %{$res->[1][1]{list}[0]{calendarEvents}})[0][0];
        $self->assert_not_null($event);
        $self->assert_str_equals($tc->{wantMethod}, $event->{method});

        my @attendees = grep { exists $_->{roles}{attendee} } values %{$event->{participants}};
        $self->assert_num_equals(1, scalar @attendees);
        $self->assert_str_equals($tc->{wantScheduleUpdated},
            $attendees[0]->{scheduleUpdated});
        $self->assert_num_equals($tc->{wantScheduleSequence},
            $attendees[0]->{scheduleSequence});
        $self->assert_str_equals($tc->{wantParticipationComment},
            $attendees[0]->{participationComment});
    }
}
