<?php

declare(strict_types=1);

namespace Drupal\flowdrop_workflow;

use Drupal\Core\Access\AccessResult;
use Drupal\Core\Access\AccessResultInterface;
use Drupal\Core\Entity\EntityAccessControlHandler;
use Drupal\Core\Entity\EntityInterface;
use Drupal\Core\Session\AccountInterface;
use Drupal\flowdrop\Constants\Permissions as FlowDropPermissions;
use Drupal\flowdrop_workflow\Constants\Permissions;

/**
 * Access control handler for FlowDrop Workflow entities.
 *
 * Splits workflow management into create / edit / delete permissions while
 * keeping 'administer flowdrop_workflow' (and the global 'administer
 * flowdrop') as supersets. All authoring permissions are security-sensitive:
 * a workflow author decides what the workflow executes.
 *
 * @internal This class is not part of the public API and may change without notice.
 */
class FlowDropWorkflowAccessControlHandler extends EntityAccessControlHandler {

  /**
   * {@inheritdoc}
   */
  protected function checkAccess(EntityInterface $entity, $operation, AccountInterface $account): AccessResultInterface {
    // Global super-admin bypass.
    if ($account->hasPermission(FlowDropPermissions::ADMINISTER_FLOWDROP)) {
      return AccessResult::allowed()->cachePerPermissions();
    }

    // Entity type admin bypass.
    if ($account->hasPermission(Permissions::ADMINISTER)) {
      return AccessResult::allowed()->cachePerPermissions();
    }

    return match ((string) $operation) {
      'view' => AccessResult::allowedIfHasPermission($account, Permissions::VIEW),
      'update' => AccessResult::allowedIfHasPermission($account, Permissions::EDIT),
      'delete' => AccessResult::allowedIfHasPermission($account, Permissions::DELETE),
      default => AccessResult::neutral()->cachePerPermissions(),
    };
  }

  /**
   * {@inheritdoc}
   */
  protected function checkCreateAccess(AccountInterface $account, array $context, $entity_bundle = NULL): AccessResultInterface {
    return AccessResult::allowedIfHasPermissions($account, [
      Permissions::CREATE,
      Permissions::ADMINISTER,
      FlowDropPermissions::ADMINISTER_FLOWDROP,
    ], 'OR');
  }

}
