<?php

declare(strict_types=1);

/*
 * This file is part of the Ferienpass package.
 *
 * (c) Richard Henkenjohann <richard@ferienpass.online>
 *
 * For more information visit the project website <https://ferienpass.online>
 * or the documentation under <https://docs.ferienpass.online>.
 */

namespace Ferienpass\CoreBundle\Tests\Notification;

use Ferienpass\CoreBundle\Notification\AccountActivatedNotification;
use Ferienpass\CoreBundle\Notification\AccountCreatedNotification;
use Ferienpass\CoreBundle\Notification\AccountRegistrationHelpNotification;
use Ferienpass\CoreBundle\Notification\ApplicationsClosedNotification;
use Ferienpass\CoreBundle\Notification\AttendanceConfirmedNotification;
use Ferienpass\CoreBundle\Notification\AttendanceDecisions;
use Ferienpass\CoreBundle\Notification\AttendanceNewlyConfirmedNotification;
use Ferienpass\CoreBundle\Notification\AttendanceRejectedNotification;
use Ferienpass\CoreBundle\Notification\DownloadNotification;
use Ferienpass\CoreBundle\Notification\HostCreatedNotification;
use Ferienpass\CoreBundle\Notification\MailingNotification;
use Ferienpass\CoreBundle\Notification\OfferCancelledNotification;
use Ferienpass\CoreBundle\Notification\OfferCompletedNotification;
use Ferienpass\CoreBundle\Notification\OfferCompleteNotification;
use Ferienpass\CoreBundle\Notification\OfferFinalizedNotification;
use Ferienpass\CoreBundle\Notification\OfferRelaunchedNotification;
use Ferienpass\CoreBundle\Notification\PaymentCreatedNotification;
use Ferienpass\CoreBundle\Notification\RemindAttendanceNotification;
use Ferienpass\CoreBundle\Notification\UserInvitationNotification;
use Ferienpass\CoreBundle\Notification\UserPasswordNotification;
use PHPUnit\Framework\TestCase;
use Symfony\Component\Notifier\Recipient\Recipient;

final class NotificationNamesTest extends TestCase
{
    public function testAccountActivatedNotificationName(): void
    {
        self::assertSame('account_activated', AccountActivatedNotification::getName());
    }

    public function testAccountActivatedAvailableTokens(): void
    {
        self::assertContains('user', AccountActivatedNotification::getAvailableTokens());
        self::assertContains('baseUrl', AccountActivatedNotification::getAvailableTokens());
    }

    public function testAccountActivatedGetChannels(): void
    {
        self::assertSame(['email'], new AccountActivatedNotification()->getChannels(new Recipient('a@b.com')));
    }

    public function testAccountCreatedNotificationName(): void
    {
        self::assertSame('account_created', AccountCreatedNotification::getName());
    }

    public function testAccountCreatedAvailableTokens(): void
    {
        self::assertContains('user', AccountCreatedNotification::getAvailableTokens());
    }

    public function testAccountCreatedGetChannels(): void
    {
        self::assertSame(['email'], new AccountCreatedNotification()->getChannels(new Recipient('a@b.com')));
    }

    public function testAccountRegistrationHelpNotificationName(): void
    {
        self::assertSame('account_registration_help', AccountRegistrationHelpNotification::getName());
    }

    public function testAccountRegistrationHelpAvailableTokens(): void
    {
        self::assertContains('user', AccountRegistrationHelpNotification::getAvailableTokens());
    }

    public function testAccountRegistrationHelpGetChannels(): void
    {
        self::assertSame(['email'], new AccountRegistrationHelpNotification()->getChannels(new Recipient('a@b.com')));
    }

    public function testApplicationsClosedNotificationName(): void
    {
        self::assertSame('applications_closed', ApplicationsClosedNotification::getName());
    }

    public function testApplicationsClosedAvailableTokens(): void
    {
        self::assertContains('offer', ApplicationsClosedNotification::getAvailableTokens());
    }

    public function testApplicationsClosedGetChannels(): void
    {
        self::assertSame(['email'], new ApplicationsClosedNotification()->getChannels(new Recipient('a@b.com')));
    }

    public function testAttendanceConfirmedNotificationName(): void
    {
        self::assertSame('attendance_confirmed', AttendanceConfirmedNotification::getName());
    }

    public function testAttendanceConfirmedAvailableTokens(): void
    {
        self::assertContains('attendance', AttendanceConfirmedNotification::getAvailableTokens());
        self::assertContains('offer', AttendanceConfirmedNotification::getAvailableTokens());
        self::assertContains('participant', AttendanceConfirmedNotification::getAvailableTokens());
    }

    public function testAttendanceDecisionsName(): void
    {
        self::assertSame('attendance_decisions', AttendanceDecisions::getName());
    }

    public function testAttendanceDecisionsAvailableTokens(): void
    {
        self::assertContains('attendances', AttendanceDecisions::getAvailableTokens());
    }

    public function testAttendanceNewlyConfirmedName(): void
    {
        self::assertSame('attendance_newly_confirmed', AttendanceNewlyConfirmedNotification::getName());
    }

    public function testAttendanceNewlyConfirmedAvailableTokens(): void
    {
        self::assertContains('attendance', AttendanceNewlyConfirmedNotification::getAvailableTokens());
    }

    public function testAttendanceRejectedNotificationName(): void
    {
        self::assertSame('attendance_withdrawn', AttendanceRejectedNotification::getName());
    }

    public function testAttendanceRejectedAvailableTokens(): void
    {
        self::assertContains('attendance', AttendanceRejectedNotification::getAvailableTokens());
        self::assertContains('offer', AttendanceRejectedNotification::getAvailableTokens());
        self::assertContains('participant', AttendanceRejectedNotification::getAvailableTokens());
    }

    public function testAttendanceRejectedGetChannels(): void
    {
        self::assertSame(['email'], new AttendanceRejectedNotification()->getChannels(new Recipient('a@b.com')));
    }

    public function testDownloadNotificationName(): void
    {
        self::assertSame('download', DownloadNotification::getName());
    }

    public function testDownloadAvailableTokens(): void
    {
        self::assertContains('filename', DownloadNotification::getAvailableTokens());
    }

    public function testDownloadGetChannels(): void
    {
        self::assertSame(['email'], new DownloadNotification()->getChannels(new Recipient('a@b.com')));
    }

    public function testHostCreatedNotificationName(): void
    {
        self::assertSame('host_created', HostCreatedNotification::getName());
    }

    public function testHostCreatedAvailableTokens(): void
    {
        self::assertContains('host', HostCreatedNotification::getAvailableTokens());
        self::assertContains('user', HostCreatedNotification::getAvailableTokens());
    }

    public function testHostCreatedGetChannels(): void
    {
        self::assertSame(['email'], new HostCreatedNotification()->getChannels(new Recipient('a@b.com')));
    }

    public function testMailingNotificationAvailableTokens(): void
    {
        self::assertContains('user', MailingNotification::getAvailableTokens());
        self::assertContains('token', MailingNotification::getAvailableTokens());
    }

    public function testMailingNotificationGetChannels(): void
    {
        self::assertSame(['email'], new MailingNotification()->getChannels(new Recipient('a@b.com')));
    }

    public function testMailingNotificationContextAndAttachments(): void
    {
        $n = new MailingNotification();
        $n->context(['foo' => 'bar']);
        self::assertSame(['foo' => 'bar'], $n->getContext());

        $n->attachments(['/tmp/file.pdf']);
        // attachments are stored internally; no getter, but no exception thrown
        $this->addToAssertionCount(1);
    }

    public function testOfferCancelledNotificationName(): void
    {
        self::assertSame('offer_cancelled', OfferCancelledNotification::getName());
    }

    public function testOfferCancelledAvailableTokens(): void
    {
        self::assertContains('attendance', OfferCancelledNotification::getAvailableTokens());
        self::assertContains('offer', OfferCancelledNotification::getAvailableTokens());
    }

    public function testOfferCompleteNotificationName(): void
    {
        self::assertSame('offer_complete', OfferCompleteNotification::getName());
    }

    public function testOfferCompleteAvailableTokens(): void
    {
        self::assertContains('offer', OfferCompleteNotification::getAvailableTokens());
    }

    public function testOfferCompleteGetChannels(): void
    {
        self::assertSame(['email'], new OfferCompleteNotification()->getChannels(new Recipient('a@b.com')));
    }

    public function testOfferCompletedNotificationName(): void
    {
        self::assertSame('offer_completed', OfferCompletedNotification::getName());
    }

    public function testOfferCompletedAvailableTokens(): void
    {
        self::assertContains('offer', OfferCompletedNotification::getAvailableTokens());
    }

    public function testOfferCompletedGetChannels(): void
    {
        self::assertSame(['email'], new OfferCompletedNotification()->getChannels(new Recipient('a@b.com')));
    }

    public function testOfferFinalizedNotificationName(): void
    {
        self::assertSame('offer_finalized', OfferFinalizedNotification::getName());
    }

    public function testOfferFinalizedAvailableTokens(): void
    {
        self::assertContains('offer', OfferFinalizedNotification::getAvailableTokens());
    }

    public function testOfferFinalizedGetChannels(): void
    {
        self::assertSame(['email'], new OfferFinalizedNotification()->getChannels(new Recipient('a@b.com')));
    }

    public function testOfferRelaunchedNotificationName(): void
    {
        self::assertSame('offer_relaunched', OfferRelaunchedNotification::getName());
    }

    public function testOfferRelaunchedAvailableTokens(): void
    {
        self::assertContains('attendance', OfferRelaunchedNotification::getAvailableTokens());
        self::assertContains('offer', OfferRelaunchedNotification::getAvailableTokens());
    }

    public function testPaymentCreatedNotificationName(): void
    {
        self::assertSame('payment_created', PaymentCreatedNotification::getName());
    }

    public function testPaymentCreatedAvailableTokens(): void
    {
        self::assertContains('payment', PaymentCreatedNotification::getAvailableTokens());
    }

    public function testRemindAttendanceNotificationName(): void
    {
        self::assertSame('remind_attendance', RemindAttendanceNotification::getName());
    }

    public function testRemindAttendanceAvailableTokens(): void
    {
        self::assertContains('attendance', RemindAttendanceNotification::getAvailableTokens());
        self::assertContains('offer', RemindAttendanceNotification::getAvailableTokens());
        self::assertContains('participant', RemindAttendanceNotification::getAvailableTokens());
        self::assertContains('attendances', RemindAttendanceNotification::getAvailableTokens());
    }

    public function testUserInvitationNotificationName(): void
    {
        self::assertSame('user_invitation', UserInvitationNotification::getName());
    }

    public function testUserInvitationAvailableTokens(): void
    {
        self::assertContains('user', UserInvitationNotification::getAvailableTokens());
        self::assertContains('host', UserInvitationNotification::getAvailableTokens());
        self::assertContains('email', UserInvitationNotification::getAvailableTokens());
    }

    public function testUserInvitationGetChannels(): void
    {
        self::assertSame(['email'], new UserInvitationNotification()->getChannels(new Recipient('a@b.com')));
    }

    public function testUserPasswordNotificationName(): void
    {
        self::assertSame('user_password', UserPasswordNotification::getName());
    }

    public function testUserPasswordAvailableTokens(): void
    {
        self::assertContains('user', UserPasswordNotification::getAvailableTokens());
        self::assertContains('token', UserPasswordNotification::getAvailableTokens());
    }

    public function testUserPasswordGetChannels(): void
    {
        self::assertSame(['email'], new UserPasswordNotification()->getChannels(new Recipient('a@b.com')));
    }
}
