<?php

namespace Ignite\Core\Tests\Unit\Files;

use Ignite\Core\Facades\FileEncryption;
use Ignite\Core\Files\File;
use Ignite\Core\Files\TemporaryFile;
use Ignite\Core\Files\TemporaryFileBuilder;
use Ignite\Core\Tests\TestCase;
use Illuminate\Foundation\Testing\WithFaker;
use Illuminate\Support\Facades\Storage;

class PGPFileEncrypterTest extends TestCase
{
    use WithFaker;

    /** @test */
    public function encrypts_to_a_specific_location()
    {
        // Arrange
        Storage::fake('some_sftp');
        Storage::fake('local');
        $file = TemporaryFileBuilder::start()->disk('some_sftp')->make($this->faker->paragraph());
        $saveFile = TemporaryFileBuilder::start()->disk('local')->extension('txt.pgp')->make();
        $pgp = FileEncryption::encrypter('pgp');

        // Execute
        $encryptedFile = $pgp->encrypt($file, $saveFile);

        // Check
        $encryptedFile->assertExists();
        $this->assertFalse($encryptedFile->is($file));
        $this->assertTrue($encryptedFile->is($saveFile));
        $this->assertInstanceOf(File::class, $encryptedFile);
        $this->assertEquals($file->get(), $pgp->decrypt($encryptedFile)->get());
    }

    /** @test */
    public function encrypts_to_a_temporary_location()
    {
        // Arrange
        Storage::fake('some_sftp');
        Storage::fake('local');
        $file = TemporaryFileBuilder::start()->disk('some_sftp')->make($this->faker->paragraph());
        $pgp = FileEncryption::encrypter('pgp');

        // Execute
        $encryptedFile = $pgp->encrypt($file);

        // Check
        $encryptedFile->assertExists();
        $this->assertFalse($encryptedFile->is($file));
        $this->assertInstanceOf(TemporaryFile::class, $encryptedFile);
        $this->assertEquals($file->get(), $pgp->decrypt($encryptedFile)->get());
    }

    /** @test */
    public function encrypts_to_the_same_location()
    {
        // Arrange
        Storage::fake('some_sftp');
        Storage::fake('local');
        $file = TemporaryFileBuilder::start()->disk('some_sftp')->make($this->faker->paragraph());
        $pgp = FileEncryption::encrypter('pgp');

        // Execute
        $encryptedFile = $pgp->encrypt($file, $file);

        // Check
        $encryptedFile->assertExists();
        $this->assertTrue($encryptedFile->is($file));
        $this->assertInstanceOf(File::class, $encryptedFile);
        $this->assertEquals($file->get(), $encryptedFile->get());
    }

    /** @test */
    public function decrypts_to_a_specific_location()
    {
        // Arrange
        Storage::fake('some_sftp');
        Storage::fake('local');
        $file = TemporaryFileBuilder::start()->disk('some_sftp')->make($this->faker->paragraph());
        $saveTo = File::new('some-save-place.txt', 'local');
        $saveTo->put($this->faker->uuid());
        $pgp = FileEncryption::encrypter('pgp');
        $encryptedFile = $pgp->encrypt($file);

        // Execute
        $decryptedFile = $pgp->decrypt($encryptedFile, $saveTo);

        // Check
        $decryptedFile->assertExists();
        $this->assertFalse($decryptedFile->is($encryptedFile));
        $this->assertInstanceOf(File::class, $decryptedFile);
        $this->assertEquals($file->get(), $decryptedFile->get());
    }

    /** @test */
    public function decrypts_to_a_temporary_location()
    {
        // Arrange
        Storage::fake('some_sftp');
        Storage::fake('local');
        $file = TemporaryFileBuilder::start()->disk('some_sftp')->make($this->faker->paragraph());
        $pgp = FileEncryption::encrypter('pgp');
        $encryptedFile = $pgp->encrypt($file);

        // Execute
        $decryptedFile = $pgp->decrypt($encryptedFile);

        // Check
        $decryptedFile->assertExists();
        $this->assertFalse($decryptedFile->is($encryptedFile));
        $this->assertInstanceOf(TemporaryFile::class, $decryptedFile);
        $this->assertEquals($file->get(), $decryptedFile->get());
    }

    /** @test */
    public function decrypts_to_the_same_location()
    {
        // Arrange
        Storage::fake('some_sftp');
        Storage::fake('local');
        $file = TemporaryFileBuilder::start()->disk('some_sftp')->make($this->faker->paragraph());
        $pgp = FileEncryption::encrypter('pgp');
        $encryptedFile = $pgp->encrypt($file);

        // Execute
        $decryptedFile = $pgp->decrypt($encryptedFile, $encryptedFile);

        // Check
        $decryptedFile->assertExists();
        $this->assertTrue($decryptedFile->is($encryptedFile));
        $this->assertInstanceOf(TemporaryFile::class, $decryptedFile);
        $this->assertEquals($file->get(), $decryptedFile->get());
    }
}
