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

use boru\ai\AI;
use boru\ai\Asset\Asset;
use boru\ai\Asset\AssetStoreInterface;
use boru\ai\Asset\ProviderAssetBinding;
use boru\ai\Runtime\RuntimeContext;
use PHPUnit\Framework\TestCase;

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

    public function testAssetFromFileReusesPersistedAssetBySha256()
    {
        $tmp = tempnam(sys_get_temp_dir(), 'ai_asset_from_file_');
        file_put_contents($tmp, 'reusable asset');
        $sha256 = hash_file('sha256', $tmp);

        $existing = new Asset();
        $existing->id('asset_existing')
            ->kind('file')
            ->filename('existing.pdf')
            ->mimeType('application/pdf')
            ->size(filesize($tmp))
            ->sha256($sha256);

        $store = new InMemoryAssetStore();
        $store->existingBySha256[$sha256] = $existing;
        AI::assetStore($store);

        $asset = AI::assetFromFile($tmp);

        $this->assertSame('asset_existing', $asset->id());
        $this->assertSame($tmp, $asset->path());
        $this->assertSame(0, $store->savedAssetCount);

        @unlink($tmp);
    }

    public function testAssetFromFileCreatesAndPersistsNewAssetWhenNoMatchExists()
    {
        $tmp = tempnam(sys_get_temp_dir(), 'ai_asset_from_file_');
        file_put_contents($tmp, 'new asset');

        $store = new InMemoryAssetStore();
        AI::assetStore($store);

        $asset = AI::assetFromFile($tmp);

        $this->assertInstanceOf(Asset::class, $asset);
        $this->assertNotSame('', $asset->id());
        $this->assertSame($tmp, $asset->path());
        $this->assertSame(basename($tmp), $asset->filename());
        $this->assertSame(filesize($tmp), $asset->size());
        $this->assertSame(hash_file('sha256', $tmp), $asset->sha256());
        $this->assertSame(1, $store->savedAssetCount);

        @unlink($tmp);
    }
}

class InMemoryAssetStore implements AssetStoreInterface
{
    public $existingBySha256 = array();
    public $savedAssetCount = 0;

    public function saveAsset(Asset $asset)
    {
        $this->savedAssetCount++;
        if (!$asset->id()) {
            $asset->id('asset_saved_' . $this->savedAssetCount);
        }
        $this->existingBySha256[$asset->sha256()] = $asset;
        return $asset;
    }

    public function loadAsset($assetId)
    {
        return false;
    }

    public function findAssetBySha256($sha256)
    {
        return isset($this->existingBySha256[$sha256]) ? $this->existingBySha256[$sha256] : false;
    }

    public function saveBinding(ProviderAssetBinding $binding)
    {
        return $binding;
    }

    public function findBinding($assetId, $provider, $purpose = null)
    {
        return false;
    }

    public function listBindings($assetId)
    {
        return array();
    }
}
