<?php

namespace AzureOss\LaravelAzureStorageBlob\Tests;

use AzureOss\LaravelAzureStorageBlob\AzureStorageBlobAdapter;
use AzureOss\LaravelAzureStorageBlob\AzureStorageBlobServiceProvider;
use AzureOss\Storage\Blob\BlobContainerClient;
use AzureOss\Storage\Blob\BlobServiceClient;
use Illuminate\Support\Facades\Http;
use Illuminate\Support\Facades\Storage;
use Orchestra\Testbench\TestCase;
use PHPUnit\Framework\Attributes\Test;

class AzureStorageBlobAdapterTest extends TestCase
{
    protected function getPackageProviders($app): array
    {
        return [AzureStorageBlobServiceProvider::class];
    }

    protected function getEnvironmentSetUp($app): void
    {
        $app['config']->set('filesystems.disks.azure', [
            'driver' => 'azure-storage-blob',
            'connection_string' => env('AZURE_STORAGE_CONNECTION_STRING'),
            'container' => env('AZURE_STORAGE_CONTAINER'),
        ]);
    }

    private static function createContainerClient(): BlobContainerClient
    {
        $connectionString = getenv('AZURE_STORAGE_CONNECTION_STRING');

        if (empty($connectionString)) {
            self::markTestSkipped('AZURE_STORAGE_CONNECTION_STRING is not provided.');
        }

        return BlobServiceClient::fromConnectionString($connectionString)->getContainerClient(
            getenv('AZURE_STORAGE_CONTAINER')
        );
    }

    public static function setUpBeforeClass(): void
    {
        self::createContainerClient()->deleteIfExists();
        self::createContainerClient()->create();
    }

    #[Test]
    public function it_resolves_from_manager(): void
    {
        self::assertInstanceOf(AzureStorageBlobAdapter::class, Storage::disk('azure'));
    }

    #[Test]
    public function driver_works(): void
    {
        $driver = Storage::disk('azure');

        // cleanup from previous test runs
        $driver->deleteDirectory('');

        self::assertFalse($driver->exists('file.text'));

        $driver->put('file.txt', 'content');

        self::assertTrue($driver->exists('file.txt'));

        self::assertEquals(
            'content',
            $driver->get('file.txt')
        );
        self::assertEquals(
            'content',
            Http::get($driver->temporaryUrl('file.txt', now()->addMinute()))->body()
        );
        self::assertEquals(
            'content',
            Http::get($driver->url('file.txt'))->body()
        );

        $driver->copy('file.txt', 'file2.txt');

        self::assertTrue($driver->exists('file2.txt'));

        $driver->move('file2.txt', 'file3.txt');

        self::assertFalse($driver->exists('file2.txt'));
        self::assertTrue($driver->exists('file3.txt'));

        // Test temporary upload URL functionality
        // Generate a temporary upload URL
        $uploadData = $driver->temporaryUploadUrl('temp-upload-test.txt', now()->addMinutes(5), [
            'content-type' => 'text/plain',
        ]);

        // Upload content directly to the URL
        $content = 'This content was uploaded directly to a temporary URL';
        $response = Http::withHeaders($uploadData['headers'])
            ->withBody($content, 'text/plain')
            ->put($uploadData['url']);

        // Verify the upload was successful
        self::assertTrue($response->successful());

        // Verify the file exists and has the correct content
        self::assertTrue($driver->exists('temp-upload-test.txt'));
        self::assertEquals($content, $driver->get('temp-upload-test.txt'));

        // Count files and clean up
        self::assertCount(3, $driver->allFiles()); // file.txt, file3.txt, and temp-upload-test.txt

        $driver->deleteDirectory('');

        self::assertCount(0, $driver->allFiles());
    }
}
