<?php

declare(strict_types=1);

namespace NoahVet\Reef\Security\IAM\Transformer;

use NoahVet\Reef\Jane\Model\GrantedPermissionShort;
use NoahVet\Reef\Jane\Model\PolicyResultPolicyResultPost;
use NoahVet\Reef\Security\Policy\PolicyResult;
use NoahVet\Reef\Security\Policy\PolicyResultGrant;

class PolicyResultTransformer
{
    /**
     * @return GrantedPermissionShort[]
     */
    public function resultGrantToGrantedPermissions(PolicyResultGrant $resultGrant): array
    {
        $allowed = \array_map(
            fn (string $permission): GrantedPermissionShort => (new GrantedPermissionShort())
                    ->setResource((string) $resultGrant->getResource())
                    ->setPrincipal($resultGrant->getPrincipal())
                    ->setPermission($permission)
                    ->setGrantType(1),
            $resultGrant->getPermissionGrants()['allow'],
        );

        $denied = \array_map(
            fn (string $permission): GrantedPermissionShort => (new GrantedPermissionShort())
                    ->setResource((string) $resultGrant->getResource())
                    ->setPrincipal($resultGrant->getPrincipal())
                    ->setPermission($permission)
                    ->setGrantType(-1),
            $resultGrant->getPermissionGrants()['deny'],
        );

        return \array_merge($allowed, $denied);
    }

    public function toWebservice(PolicyResult $policyResult): PolicyResultPolicyResultPost
    {
        $ret = new PolicyResultPolicyResultPost();

        $ret->setName($policyResult->getPolicyName());
        $ret->setSubject($policyResult->getSubject());
        $ret->setEtag($policyResult->etag ?? '');

        $grants = \array_map(
            [$this, 'resultGrantToGrantedPermissions'],
            $policyResult->getGrants(),
        );

        if (empty($grants)) {
            $ret->setGrants([]);
        } else {
            $ret->setGrants(\array_values(\array_merge(...$grants)));
        }

        return $ret;
    }
}
