<?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\DocStoreBundle\Tests\GenericDoc;

use Chill\DocStoreBundle\GenericDoc\FetchQueryToSqlBuilder;
use Chill\DocStoreBundle\GenericDoc\FetchQuery;
use Doctrine\DBAL\Types\Types;
use Symfony\Bundle\FrameworkBundle\Test\KernelTestCase;

/**
 * @internal
 *
 * @coversNothing
 */
class FetchQueryToSqlBuilderTest extends KernelTestCase
{
    public function testToSql(): void
    {
        $query = new FetchQuery(
            'test',
            'jsonb_build_object(\'id\', a.column)',
            'a.datecolumn',
            'my_table a'
        );
        $query->addJoinClause('LEFT JOIN other b ON a.id = b.foreign_id', ['foo'], [Types::STRING]);
        $index = $query->addJoinClause('LEFT JOIN other c ON a.id = c.foreign_id', ['bar'], [Types::STRING]);
        $query->addJoinClause('LEFT JOIN other d ON a.id = d.foreign_id', ['bar_baz'], [Types::STRING]);
        $query->removeJoinClause($index);
        $query->addWhereClause('b.item = ?', ['baz'], [Types::STRING]);
        $index = $query->addWhereClause('b.cancel', ['foz'], [Types::STRING]);
        $query->removeWhereClause($index);

        ['sql' => $sql, 'params' => $params, 'types' => $types] = (new FetchQueryToSqlBuilder())->toSql($query);

        $filteredSql =
            implode(' ', array_filter(
                explode(' ', str_replace("\n", '', $sql)),
                fn (string $tok) => '' !== $tok
            ))
        ;

        self::assertEquals(
            "SELECT 'test' AS key, jsonb_build_object('id', a.column) AS identifiers, ".
            'a.datecolumn::date AS doc_date FROM my_table a LEFT JOIN other b ON a.id = b.foreign_id LEFT JOIN other d ON a.id = d.foreign_id WHERE b.item = ?',
            $filteredSql
        );
        self::assertEquals(['foo', 'bar_baz', 'baz'], $params);
        self::assertEquals([Types::STRING, Types::STRING, Types::STRING], $types);
    }

    public function testToSqlWithoutWhere(): void
    {
        $query = new FetchQuery(
            'test',
            'jsonb_build_object(\'id\', a.column)',
            'a.datecolumn',
            'my_table a'
        );

        ['sql' => $sql, 'params' => $params, 'types' => $types] = (new FetchQueryToSqlBuilder())->toSql($query);

        $filteredSql =
            implode(' ', array_filter(
                explode(' ', str_replace("\n", '', $sql)),
                fn (string $tok) => '' !== $tok
            ))
        ;

        self::assertEquals(
            "SELECT 'test' AS key, jsonb_build_object('id', a.column) AS identifiers, ".
            'a.datecolumn::date AS doc_date FROM my_table a',
            $filteredSql
        );
        self::assertEquals([], $params);
        self::assertEquals([], $types);
    }
}
