<?php

namespace NoahVet\Reef\Test\A_Unit\Iterator;

use NoahVet\Reef\Iterator\ApiClientChunkedReefIteratorDecorator;
use NoahVet\Reef\Iterator\ReefApiIteratorInterface;
use PHPUnit\Framework\MockObject\MockObject;
use PHPUnit\Framework\TestCase;

class ApiClientChunkedReefIteratorDecoratorTest extends TestCase
{
    /**
     * @var ReefApiIteratorInterface&MockObject
     */
    private ReefApiIteratorInterface $iterator;

    protected function setUp(): void
    {
        $this->iterator = $this->createMock(ReefApiIteratorInterface::class);
    }

    public function testOneChunk(): void
    {
        $arrayIterator = new \ArrayIterator([new \stdClass(), new \stdClass()]);

        $this->iterator
            ->method('getParams')
            ->willReturn(['id' => [1, 2, 3, 4]])
        ;

        $invokedSetParamsCount = self::exactly(2);
        $setParamsCall = 0;
        $this->iterator
            ->expects($invokedSetParamsCount)
            ->method('setParams')
            ->willReturnCallback(function (array $params) use (&$setParamsCall, $arrayIterator): void {
                ++$setParamsCall;

                if (1 === $setParamsCall) {
                    $this->assertSame(['id' => [1, 2]], $params);
                }

                if (2 === $setParamsCall) {
                    $this->assertSame(['id' => [3, 4]], $params);
                }

                $arrayIterator->rewind();
            })
        ;

        $this->iterator
            ->method('next')
            ->willReturnCallback(static fn () => $arrayIterator->next())
        ;

        $this->iterator
            ->method('key')
            ->willReturnCallback(static fn () => $arrayIterator->key())
        ;

        $this->iterator
            ->method('current')
            ->willReturnCallback(static fn () => $arrayIterator->current())
        ;

        $this->iterator
            ->method('valid')
            ->willReturnCallback(static fn () => $arrayIterator->valid())
        ;

        $decorator = new ApiClientChunkedReefIteratorDecorator($this->iterator, 'id', 2);

        $result = \iterator_to_array($decorator);

        $this->assertCount(4, $result);
    }
}
