<?php

declare(strict_types=1);
namespace Tests\Adawolfa\Retrofit;
use Adawolfa\Retrofit\Executor;
use Adawolfa\Retrofit\Factory;
use Adawolfa\Retrofit\GeneratorException;
use Adawolfa\Retrofit\HTTP\GET;
use Adawolfa\Retrofit\HTTP\HTTP;
use Adawolfa\Retrofit\Implementation;
use Http\Mock\Client;
use ReflectionAttribute;
use ReflectionException;

final class GeneratorTest extends TestCase
{

	public function testService(): void
	{
		$reflection = self::createReflection(Service::class);
		$this->assertSame('__GC__\Retrofit\TestsAdawolfaRetrofit\Service', $reflection->name);
		$this->assertTrue($reflection->isInstantiable());
		$this->assertTrue($reflection->isFinal());
		$this->assertSame(Implementation::class, $reflection->getParentClass()->name);
	}

	public function testInstantiate(): void
	{
		$instance = (new Factory)
			->withExecutor(new Executor(new Client))
			->create(Service::class);
		$this->assertInstanceOf('__GC__\Retrofit\TestsAdawolfaRetrofit\Service', $instance);
	}

	/**
	 * @throws ReflectionException
	 */
	public function testMethodAttributeOverride(): void
	{
		$reflection = self::createReflection(Service::class);
		$method     = $reflection->getMethod('root');
		$this->assertInstanceOf(
			GET::class,
			$method->getAttributes(HTTP::class, ReflectionAttribute::IS_INSTANCEOF)[0]->newInstance(),
		);
	}

	public function testMethodNoVerb(): void
	{
		$this->expectException(GeneratorException::class);
		$this->expectExceptionMessage('Tests\Adawolfa\Retrofit\ParentService::root() must declare an HTTP verb, such as #[GET].');
		self::createReflection(ServiceNoVerb::class);
	}

}