<?php

namespace Acms\Services\ConfigSet;

use Acms\Services\Facades\Application as App;
use Acms\Services\Auth\Contracts\Guard;

/**
 * コンフィグセット機能（エクスポート・インポート）の認可判定を集約する。
 *
 * config_set 専用のロール権限は存在しないため、コンフィグ編集権限（`config_edit`、
 * DB上は role_config_edit 列）を流用する。各ハンドラ（ACMS_POST_Config_Set_Export /
 * Import）から共通利用する。
 *
 * 判定対象のユーザーは引数で受け取り、テスト時に任意のユーザーを差し込めるようにする。
 * ロール運用時はロールガードを直接利用し（Auth ファサードはガード選択がセッション
 * ユーザー（SUID）基準になるため）、引数で受け取ったユーザーを基準に評価する
 * （{@see \Acms\Services\Form\Authorization} と同じ設計方針）。ロール未使用時は
 * sessionWithAdministration の第3引数 userId に引数のユーザーを渡して評価する
 * （cache は無効化し、判定対象ユーザーが呼び出しごとに変わることを反映する）。
 * sessionWithAdministration 自身が isPermissionOfAdministrator + timemachineMode の
 * 判定をまとめて持つため、ここで同じ判定ロジックを再実装せずに済み、将来 sessionWith*
 * 側にガードが追加された場合も自動的に追従できる。
 */
class Authorization
{
    /**
     * コンフィグセットのエクスポート・インポートが許可されているか
     *
     * @param int $userId 判定対象のユーザーID（通常はログイン中のユーザー SUID）
     * @param int $blogId 対象ブログID
     * @return bool
     */
    public function canManage(int $userId, int $blogId): bool
    {
        if ($userId < 1) {
            return false;
        }

        if (roleAvailableUser($userId)) {
            return $this->roleGuard()->roleAuthorization('config_edit', $blogId, 0, $userId);
        }

        return sessionWithAdministration($blogId, ['cache' => false], $userId);
    }

    /**
     * ロールベースの権限判定ガードを取得する。
     *
     * @return \Acms\Services\Auth\Contracts\Guard
     */
    private function roleGuard(): Guard
    {
        $guard = App::make('auth.role');
        assert($guard instanceof Guard);

        return $guard;
    }
}
