<?php
declare(strict_types=1);

namespace SwaggerBake\Test\TestCase\Lib\Attribute;

use Cake\Routing\Router;
use Cake\Routing\RouteBuilder;
use Cake\TestSuite\TestCase;

use SwaggerBake\Lib\Attribute\OpenApiHeader;
use SwaggerBake\Lib\Attribute\OpenApiQueryParam;
use SwaggerBake\Lib\Exception\SwaggerBakeRunTimeException;
use SwaggerBake\Lib\Model\ModelScanner;
use SwaggerBake\Lib\Route\RouteScanner;
use SwaggerBake\Lib\Configuration;
use SwaggerBake\Lib\Swagger;

class OpenApiQueryParamTest extends TestCase
{
    /**
     * @var string[]
     */
    public array $fixtures = [
        'plugin.SwaggerBake.Departments',
    ];

    private Configuration $config;

    public function setUp(): void
    {
        parent::setUp(); // TODO: Change the autogenerated stub
    }

    public function test_openapi_query(): void
    {
        $this->__setUp();
        $cakeRoute = new RouteScanner(new Router(), $this->config);

        $swagger = (new Swagger(new ModelScanner($cakeRoute, $this->config), $this->config))->build();
        $arr = json_decode($swagger->toString(), true);

        $this->assertArrayHasKey('/departments', $arr['paths']);
        $this->assertArrayHasKey('get', $arr['paths']['/departments']);
        $operation = $arr['paths']['/departments']['get'];

        $this->assertCount(1, array_filter($operation['parameters'], function ($param) {
            return isset($param['name']) && $param['name'] == 'random';
        }));
    }

    public function test_constructor_expect_exception_from_missing_name_and_ref(): void
    {
        $this->expectException(SwaggerBakeRunTimeException::class);
        new OpenApiQueryParam();
    }

    public function test_constructor_expect_exception_from_invalid_type(): void
    {
        $this->expectException(SwaggerBakeRunTimeException::class);
        new OpenApiQueryParam(name: 'Name', type: 'invalid');
    }

    private function __setUp(): void
    {
        Router::createRouteBuilder('/')->scope('/', function (RouteBuilder $builder) {
            $builder->setExtensions(['json']);
            $builder->resources('Departments');
        });

        $this->config = new Configuration([
            'prefix' => '/',
            'yml' => '/config/swagger-bare-bones.yml',
            'json' => '/webroot/swagger.json',
            'webPath' => '/swagger.json',
            'hotReload' => false,
            'exceptionSchema' => 'Exception',
            'requestAccepts' => ['application/x-www-form-urlencoded'],
            'responseContentTypes' => ['application/json'],
            'namespaces' => [
                'controllers' => ['\SwaggerBakeTest\App\\'],
                'entities' => ['\SwaggerBakeTest\App\\'],
                'tables' => ['\SwaggerBakeTest\App\\'],
            ]
        ], SWAGGER_BAKE_TEST_APP);
    }
}