<?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\Schema;
use GraphQL\Utils\BuildSchema;
use PHPUnit\Framework\TestCase;

class EnumModelGeneratorTest 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();

        $type = $schema->getType($typeName);
        foreach ($generator->generateType($type, $schema) as $item) {
            $code = $item;
            break;
        }
        $this->assertTrue(isset($code));

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

        FileSystemHelper::rmdir($dir);
    }

    public function dataProviderGeneratePhpCode(): iterable
    {
        yield [
            'Status',
            CodeGeneratorConfig::V7_4,
            BuildSchema::build(Parser::parse(<<<GQL
"TRANSACTION STATUS DOC"
enum Status {
    NEW
    IN_PROGRESS
    "SUCCESS DOC"
    SUCCESS
    FAIL
}
GQL
            )),<<<'PHP'
<?php

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

use Axtiva\FlexibleGraphql\Generator\Exception\UnknownEnumValue;
use Axtiva\FlexibleGraphql\Type\EnumInterface;

/**
 * This code is @generated by axtiva/flexible-graphql-php
 * and will be regenerated. Do not edit it manually
 * PHP representation of graphql enum Status
 * TRANSACTION STATUS DOC
 */
final class StatusEnum implements EnumInterface
{
    public const NEW = 'NEW';
    public const IN_PROGRESS = 'IN_PROGRESS';
    /**
     * SUCCESS DOC
     */
    public const SUCCESS = 'SUCCESS';
    public const FAIL = 'FAIL';
    public string $value;
    private static array $map = [
        self::NEW => true,
        self::IN_PROGRESS => true,
        self::SUCCESS => true,
        self::FAIL => true,
    ];

    public function __construct($value)
    {
        if (!isset(self::$map[$value])) {
            throw new UnknownEnumValue(__CLASS__, $value);
        }
        $this->value = $value;
    }

    public function __toString(): string
    {
        return $this->value;
    }
}
PHP
            ,];
    }
}