<?php

declare(strict_types=1);

namespace NoahVet\Reef\Test\A_Unit\Security\IAM\Transformer;

use NoahVet\Reef\Security\IAM\Model\Resource;
use NoahVet\Reef\Security\IAM\Model\ResourceType;
use NoahVet\Reef\Security\IAM\Transformer\PolicyResultTransformer;
use NoahVet\Reef\Security\Policy\PolicyResult;
use NoahVet\Reef\Security\Policy\PolicyResultGrant;
use PHPUnit\Framework\TestCase;

class PolicyResultTransformerTest extends TestCase
{
    public function testResultGrantToGrantedPermissions(): void
    {
        $transformer = new PolicyResultTransformer();

        $policyResultGrant = new PolicyResultGrant(
            Resource::fromString('reef:phpunit:resource', 'test'),
            'reef:phpunit:principal:test',
            [
                'allow' => ['permission1', 'permission2'],
                'deny' => ['permission3'],
            ],
        );

        $grants = $transformer->resultGrantToGrantedPermissions($policyResultGrant);

        self::assertCount(3, $grants);
        // Check resource and principal
        foreach ($grants as $grant) {
            self::assertEquals('reef:phpunit:resource:test', $grant->getResource());
            self::assertEquals('reef:phpunit:principal:test', $grant->getPrincipal());
        }

        self::assertEquals('permission1', $grants[0]->getPermission());
        self::assertEquals(1, $grants[0]->getGrantType());
        self::assertEquals('permission2', $grants[1]->getPermission());
        self::assertEquals(1, $grants[1]->getGrantType());
        self::assertEquals('permission3', $grants[2]->getPermission());
        self::assertEquals(-1, $grants[2]->getGrantType());
    }

    public function testToWebservice(): void
    {
        $transformer = new PolicyResultTransformer();

        $policyResultGrant = new PolicyResultGrant(
            Resource::fromString('reef:phpunit:resource', 'test'),
            'reef:phpunit:principal:test',
            [
                'allow' => ['permission1', 'permission2'],
                'deny' => ['permission3'],
            ],
        );
        $policyResult = new PolicyResult(
            'phpunitpolicy',
            'internalid',
            ResourceType::fromString('reef:phpunit:resource'),
        );
        $policyResult->etag = 'etag';
        $policyResult->addGrant($policyResultGrant);

        $payload = $transformer->toWebservice($policyResult);

        self::assertEquals('phpunitpolicy', $payload->getName());
        self::assertEquals('internalid', $payload->getSubject());
        self::assertEquals('etag', $payload->getEtag());

        // Detail is checked in testResultGrantToGrantedPermissions
        self::assertCount(3, $payload->getGrants());

        $policyResult = new PolicyResult(
            'phpunitpolicy',
            'internalid',
            ResourceType::fromString('reef:phpunit:resource'),
        );
        $policyResult->etag = 'etag';
        $payload = $transformer->toWebservice($policyResult);

        self::assertEquals('phpunitpolicy', $payload->getName());
        self::assertEquals('internalid', $payload->getSubject());
        self::assertEquals('etag', $payload->getEtag());

        // Detail is checked in testResultGrantToGrantedPermissions
        self::assertCount(0, $payload->getGrants());
    }
}
