<?php

declare(strict_types=1);

namespace App\Tests;

use PHPUnit\Framework\TestCase;
use App\Notification\Notification;
use App\Notification\NotificationInterface;
use PHPUnit\Framework\Attributes\DataProvider;
use Exception;

final class NotificationTest extends TestCase
{
    /** @var array<string, string> */
    private static array $config = ['type' => 'ntfy', 'domain' => 'https://test.com', 'topic' => 'testing'];

    public function testloadSingle(): void
    {
        $dut = new Notification();
        $dut->loadSingle('ntfy', self::$config);
        $this->assertEquals(1, count($dut->getNotifiers()));

        $dut->loadSingle('Ntfy', self::$config);
        $this->assertEquals(2, count($dut->getNotifiers()));

        $dut->loadSingle('NTFY', self::$config);
        $this->assertEquals(3, count($dut->getNotifiers()));

        $dut->loadSingle('invalid', self::$config);
        $this->assertEquals(3, count($dut->getNotifiers()));
    }

    public function testloadMany(): void
    {
        $dut = new Notification();

        $arr = [];
        $arr[] = self::$config;
        $arr[] = self::$config;
        $arr[] = self::$config;
        $arr[] = self::$config;
        $dut->loadMany($arr);

        $this->assertEquals(4, count($dut->getNotifiers()));
    }

    public function testSendNoNotifier(): void
    {
        $dut = new Notification();
        $dut->send('title', 'topic');
        $this->assertEquals(0, count($dut->getNotifiers()));
    }

    public function testSendOneNotifier(): void
    {
        $dut = new Notification();
        $mock1 = $this->createMock(NotificationInterface::class);
        $dut->addNotifier($mock1);
        $mock1->expects($this->once())->method('send');
        $dut->send('title', 'topic');
    }

    public function testSendMoreNotifiers(): void
    {
        $dut = new Notification();
        $mock1 = $this->createMock(NotificationInterface::class);
        $mock2 = $this->createMock(NotificationInterface::class);
        $dut->addNotifier($mock1);
        $dut->addNotifier($mock2);
        $mock1->expects($this->once())->method('send');
        $mock2->expects($this->once())->method('send');
        $dut->send('title', 'topic');
    }

    public function testSendErrorInNotifiers(): void
    {
        $dut = new Notification();
        $mock1 = $this->createMock(NotificationInterface::class);
        $mock2 = $this->createMock(NotificationInterface::class);
        $dut->addNotifier($mock1);
        $dut->addNotifier($mock2);
        $mock1->expects($this->once())->method('send')->willThrowException(new Exception());
        $mock2->expects($this->once())->method('send');
        $dut->send('title', 'topic');
    }
}