<?php

namespace Axtiva\FlexibleGraphql\Tests\Generator\Model\Psr4;

use Axtiva\FlexibleGraphql\Builder\Foundation\CodeGeneratorBuilder;
use Axtiva\FlexibleGraphql\Generator\Config\Foundation\Psr4\CodeGeneratorConfig;
use Axtiva\FlexibleGraphql\Tests\Helper\FileSystemHelper;
use GraphQL\Language\Parser;
use GraphQL\Type\Definition\CustomScalarType;
use GraphQL\Type\Schema;
use GraphQL\Utils\BuildSchema;
use PHPUnit\Framework\TestCase;

class ScalarResolverGeneratorTest extends TestCase
{
    /**
     * @return void
     * @dataProvider dataProviderGeneratePhpCode
     */
    public function testGeneratePhpCode(
        string $typeName,
        string $languageLevel,
        Schema $schema,
        string $expected
    ) {
        $namespace = 'Axtiva\FlexibleGraphql\Example\GraphQL';
        $dir = uniqid('/tmp/TmpTestData/GraphQL');

        FileSystemHelper::rmdir($dir);
        FileSystemHelper::mkdir($dir);

        $builder = new CodeGeneratorBuilder(new CodeGeneratorConfig($dir, $languageLevel, $namespace));

        $generator = $builder->build();

        /** @var CustomScalarType $type */
        $type = $schema->getType($typeName);
        $this->assertInstanceOf(CustomScalarType::class, $type);

        $code = $generator->generateScalarResolver($type, $schema);
        $this->assertTrue(isset($code));

        $this->assertEquals($expected, file_get_contents($code->getFilename()));

        FileSystemHelper::rmdir($dir);
    }

    public function dataProviderGeneratePhpCode(): iterable
    {
        yield [
            'DateTime',
            CodeGeneratorConfig::V7_4,
            BuildSchema::build(Parser::parse(<<<GQL
scalar DateTime
GQL
            )),<<<'PHP'
<?php

declare (strict_types=1);
namespace Axtiva\FlexibleGraphql\Example\GraphQL\Scalar;

use GraphQL\Language\AST\Node;
use Axtiva\FlexibleGraphql\Resolver\TypedCustomScalarResolverInterface;
use Axtiva\FlexibleGraphql\Generator\Exception\NotImplementedResolver;

/**
 * This code is @generated by axtiva/flexible-graphql-php
 * This is resolver for scalar DateTime
 */
final class DateTimeScalar implements TypedCustomScalarResolverInterface
{
    public static function getTypeName(): ?string
    {
        return null;
        // Return type name of scalar for support autocompleate and type checking,
        // use class name or any scalar name like array, string, int, ...
        // Example: return \DateTimeImmutable::class;
    }

    public function serialize($value)
    {
        throw new NotImplementedResolver('Not implemented field resolver ' . __CLASS__);
        // Not implemented. Return here string representation of your scalar value or null if it is empty
        // Example: return $value->format(DateTimeImmutable::ISO8601);
    }

    public function parseValue($value)
    {
        throw new NotImplementedResolver('Not implemented field resolver ' . __CLASS__);
        // Not implemented. Return here Code representation of your scalar value or null if it is empty
        // Example: return $value ? new DateTimeImmutable($value) : null;
    }

    public function parseLiteral(Node $value, ?array $variables = null)
    {
        throw new NotImplementedResolver('Not implemented field resolver ' . __CLASS__);
        // Not implemented. Return here Code representation of your scalar value or null if it is empty
        // Example: return $value->value ? new DateTimeImmutable((string) $value->value) : null;
    }
}
PHP
            ,];
    }
}