<?php

namespace Tests\Feature;

use Carbon\Carbon;
use Illuminate\Contracts\Filesystem\FileNotFoundException;
use Illuminate\Foundation\Testing\DatabaseTransactions;
use Tests\TestCase;

use App\Classes\FTN\Tic;
use App\Models\{Address,Filearea};
use App\Exceptions\{InvalidCRCException,
	InvalidPasswordException,
	NodeNotSubscribedException,
	NoWriteSecurityException};
use App\Exceptions\TIC\{NoFileAreaException,NotToMeException,SizeMismatchException};

/**
 * Test TIC processing
 *
 * + TIC file with no file
 * + TIC file with file wrong size
 * + TIC file with file wrong CRC
 * + TIC file from host with no write
 * + TIC file not to me
 * + TIC file no filearea here
 * + TIC file from host no area
 * + TIC file from host no exports
 * + TIC file invalid password
 * + TIC export
 *
 */

class TicProcessingTest extends TestCase
{
	use DatabaseTransactions;

	public function test_tic_nofile(): void
	{
		$this->expectException(FileNotFoundException::class);

		$tic = new Tic;
		$tic->load('file/000E-1700545740-no_file.tic');
	}

	public function test_tic_invalidcrc(): void
	{
		$this->expectException(InvalidCRCException::class);

		$tic = new Tic;
		$tic->load('file/000E-1700545740-invalid_crc.tic');
	}

	public function test_tic_nofilearea(): void
	{
		$this->expectException(NoFileAreaException::class);

		$tic = new Tic;
		$tic->load('file/000E-1700545740-no_area.tic');
	}

	public function test_tic_bad_size(): void
	{
		$this->expectException(SizeMismatchException::class);

		$tic = new Tic;
		$tic->load('file/000E-1700545740-bad_size.tic');
	}

	public function test_tic_not_to_me(): void
	{
		$this->expectException(NotToMeException::class);

		$tic = new Tic;
		$tic->load('file/000E-1700545740-not_to_me.tic');
	}

	public function test_tic_wrong_password(): void
	{
		// Configure a node address
		$ao = Address::findFTN('100:1/0@a');
		$ao->system->sessions()->attach($ao->zone_id,['ticpass'=>'PASSWORD']);

		$this->expectException(InvalidPasswordException::class);

		$tic = new Tic;
		$tic->load('file/000E-1700545740-wrong_password.tic');
	}

	public function test_tic_node_not_subscribed(): void
	{
		// Configure a node address
		$ao = Address::findFTN('100:1/0@a');
		$ao->system->sessions()->attach($ao->zone_id,['ticpass'=>'PASSWORD']);

		$this->expectException(NodeNotSubscribedException::class);

		$tic = new Tic;
		$tic->load('file/000E-1700545740-file.tic');
	}

	public function test_tic_node_no_write(): void
	{
		// Configure a node address
		$ao = Address::findFTN('100:1/0@a');
		$ao->system->sessions()->attach($ao->zone_id,['ticpass'=>'PASSWORD']);
		$ao->fileareas()->syncWithPivotValues(Filearea::where('name','FILE_AREA')->single()->id,['subscribed'=>Carbon::now()]);

		$this->expectException(NoWriteSecurityException::class);

		$tic = new Tic;
		$tic->load('file/000E-1700545740-file.tic');
	}

	public function test_tic_good(): void
	{
		// Configure a node address
		$ao = Address::findFTN('100:1/0@a');
		$ao->system->sessions()->attach($ao->zone_id,['ticpass'=>'PASSWORD']);
		$ao->fileareas()->syncWithPivotValues(Filearea::where('name','FILE_AREA')->single()->id,['subscribed'=>Carbon::now()]);
		$ao->unguard();
		$ao->update(['security'=>1]);

		$tic = new Tic;
		$file = $tic->load('file/000E-1700545740-file.tic');

		$tic->save();

		$this->assertModelExists($file);

		$file->refresh();
		$this->assertEquals('100:1/0',$file->fftn->ftn3d);
		$this->assertEquals('100:10/11',$file->origin->ftn3d);
		$this->assertCount(7,$file->seenby);
		$this->assertCount(4,$file->path);
	}
}