<?php
namespace boru\ai\Tests\Asset;

use boru\ai\AI;
use boru\ai\Asset\Asset;
use boru\ai\Asset\AssetProviderInterface;
use boru\ai\Asset\AssetProviderRegistry;
use boru\ai\Asset\NullAssetStore;
use boru\ai\Asset\ProviderAssetBinding;
use boru\ai\Runtime\RuntimeContext;
use PHPUnit\Framework\TestCase;

class AssetProviderRegistryTest extends TestCase
{
    protected function setUp(): void
    {
        AI::runtimeContext(new RuntimeContext());
    }

    public function testRegistryStoresAndResolvesProvidersByName()
    {
        $registry = new AssetProviderRegistry();
        $provider = new TestAssetProvider('openai', 'file_openai_1');

        $registry->register($provider);

        $this->assertTrue($registry->has('openai'));
        $this->assertSame($provider, $registry->get('openai'));
        $this->assertCount(1, $registry->all());
    }

    public function testAIAttachAssetUsesRegisteredProviderAndAddsAttachmentAndBinding()
    {
        $registry = new AssetProviderRegistry();
        $registry->register(new TestAssetProvider('openai', 'file_openai_1'));
        AI::assetProviders($registry);
        AI::assetStore(new NullAssetStore());

        $asset = new Asset();
        $asset->id('asset_pdf_1')
            ->kind('file')
            ->path('/tmp/example.pdf')
            ->filename('example.pdf')
            ->mimeType('application/pdf');

        $ai = AI::provider('openai')->model('gpt-5.1');
        $ai->attachAsset($asset, 'user_data', 'file');

        $request = $ai->request();
        $this->assertCount(1, $request->attachments());
        $this->assertCount(1, $request->assetBindings());
        $this->assertSame('asset_pdf_1', $request->attachments()[0]->assetId());
        $this->assertSame('file', $request->attachments()[0]->kind());
        $this->assertSame('openai', $request->assetBindings()[0]->provider());
        $this->assertSame('file_openai_1', $request->assetBindings()[0]->providerAssetId());
    }
}

class TestAssetProvider implements AssetProviderInterface
{
    /** @var string */
    protected $providerName;

    /** @var string */
    protected $providerAssetId;

    public function __construct($providerName, $providerAssetId)
    {
        $this->providerName = $providerName;
        $this->providerAssetId = $providerAssetId;
    }

    public function providerName()
    {
        return $this->providerName;
    }

    public function ensureBinding(Asset $asset, $purpose = null, ProviderAssetBinding $existingBinding = null)
    {
        if ($existingBinding instanceof ProviderAssetBinding) {
            return $existingBinding;
        }

        $binding = new ProviderAssetBinding();
        $binding->assetId($asset->id());
        $binding->provider($this->providerName());
        $binding->providerAssetId($this->providerAssetId);
        $binding->purpose($purpose);
        $binding->status('ready');
        $binding->mimeType($asset->mimeType());
        return $binding;
    }
}
