<?php

declare(strict_types=1);

/*
 * Chill is a software for social workers
 *
 * For the full copyright and license information, please view
 * the LICENSE file that was distributed with this source code.
 */

namespace Chill\DocGeneratorBundle\Tests\Serializer\Encoder;

use Chill\DocGeneratorBundle\Serializer\Encoder\DocGenEncoder;
use PHPUnit\Framework\TestCase;
use Symfony\Component\Serializer\Exception\UnexpectedValueException;

/**
 * @internal
 *
 * @coversNothing
 */
final class DocGenEncoderTest extends TestCase
{
    private DocGenEncoder $encoder;

    protected function setUp(): void
    {
        parent::setUp();

        $this->encoder = new DocGenEncoder();
    }

    public function testEmbeddedLoopsThrowsException()
    {
        $this->expectException(UnexpectedValueException::class);

        $data = [
            'data' => [
                ['item' => 'one'],
                [
                    'embedded' => [
                        [
                            ['subitem' => 'two'],
                            ['subitem' => 'three'],
                        ],
                    ],
                ],
            ],
        ];

        $this->encoder->encode($data, 'docgen');
    }

    /**
     * @dataProvider generateEncodeData
     */
    public function testEncode(mixed $expected, mixed $data, string $msg)
    {
        $generated = $this->encoder->encode($data, 'docgen');
        $this->assertEquals($expected, $generated, $msg);
    }

    public static function generateEncodeData()
    {
        yield [['tests' => 'ok'], ['tests' => 'ok'], 'A simple test with a simple array'];

        yield [
            // expected:
            ['item_subitem' => 'value'],
            // data:
            ['item' => ['subitem' => 'value']],
            'A test with multidimensional array',
        ];

        yield [
            // expected:
            ['data' => [['item' => 'one'], ['item' => 'two']]],
            // data:
            ['data' => [['item' => 'one'], ['item' => 'two']]],
            'a list of items',
        ];

        yield [
            // expected:
            ['data' => [['item_subitem' => 'alpha'], ['item' => 'two']]],
            // data:
            ['data' => [['item' => ['subitem' => 'alpha']], ['item' => 'two']]],
            'a list of items with multidimensional array inside item',
        ];

        yield [
            // expected:
            [
                'persons' => [
                    [
                        'firstname' => 'Jonathan',
                        'lastname' => 'Dupont',
                        'dateOfBirth_long' => '16 juin 1981',
                        'dateOfBirth_short' => '16/06/1981',
                        'father_firstname' => 'Marcel',
                        'father_lastname' => 'Dupont',
                        'father_dateOfBirth_long' => '10 novembre 1953',
                        'father_dateOfBirth_short' => '10/11/1953',
                    ],
                ],
            ],
            // data:
            [
                'persons' => [
                    [
                        'firstname' => 'Jonathan',
                        'lastname' => 'Dupont',
                        'dateOfBirth' => ['long' => '16 juin 1981', 'short' => '16/06/1981'],
                        'father' => [
                            'firstname' => 'Marcel',
                            'lastname' => 'Dupont',
                            'dateOfBirth' => ['long' => '10 novembre 1953', 'short' => '10/11/1953'],
                        ],
                    ],
                ],
            ],
            'a longer list, with near real data inside and embedded associative arrays',
        ];
    }
}
