<?php

declare(strict_types=1);

require dirname(__DIR__) . '/app/bootstrap.php';

use App\Core\AccessControl;
use App\Repositories\AccessControlRepository;

$siteAdmin = trim((string)($argv[1] ?? '7124'));

try {
    $repository = new AccessControlRepository();
    $schemaReady = $repository->schemaReady();
    $roles = $schemaReady ? $repository->listRoles() : [];
    $counts = $schemaReady
        ? $repository->accessCounts()
        : [
            'site_admins' => 0,
            'general_managers' => 0,
            'configured_users' => 0,
        ];
    $context = $schemaReady
        ? $repository->contextForUser($siteAdmin)
        : [];

    $roleMap = [];
    foreach ($roles as $role) {
        $roleMap[(string)($role['role_code'] ?? '')] = $role;
    }

    $siteAdminRoles = array_map(
        static function (array $row): string {
            return (string)($row['role_code'] ?? '');
        },
        (array)($context['roles'] ?? [])
    );

    $duplicateRoleRows = [];
    if ($schemaReady) {
        $reflection = new ReflectionClass($repository);
        $property = $reflection->getProperty('hospitalCode');
        $property->setAccessible(true);
        $branch = (string)$property->getValue($repository);

        $duplicateRoleRows = \App\Core\Database::fetchAll($branch, "
            SELECT USERNAME username, COUNT(*) role_count
            FROM DASH_ACL_USER_ROLES
            WHERE NVL(IS_ACTIVE, 1) = 1
              AND ROLE_CODE IN ('SITE_ADMIN', 'GENERAL_MANAGER')
            GROUP BY USERNAME
            HAVING COUNT(*) > 1
        ");
    }

    $permissions = AccessControl::permissions();
    $businessCategories = (array)config(
        'access_control.business_categories',
        ['business', 'reporting', 'workflow']
    );
    $businessPermissionCount = 0;
    $administrationPermissionCount = 0;
    foreach ($permissions as $permission) {
        $category = (string)($permission['category'] ?? 'business');
        if (in_array($category, $businessCategories, true)) {
            $businessPermissionCount++;
        } else {
            $administrationPermissionCount++;
        }
    }

    $checks = [
        'schema_ready' => $schemaReady,
        'site_admin_role_ready' => isset($roleMap['SITE_ADMIN']),
        'general_manager_role_ready' => isset($roleMap['GENERAL_MANAGER']),
        'site_admin_policy_all' =>
            (string)($roleMap['SITE_ADMIN']['policy_mode'] ?? '') === 'ALL',
        'general_manager_policy_business' =>
            (string)($roleMap['GENERAL_MANAGER']['policy_mode'] ?? '')
            === 'ALL_BUSINESS',
        'site_admin_exists' => (int)$counts['site_admins'] >= 1,
        'requested_site_admin_assigned' => in_array(
            'SITE_ADMIN',
            $siteAdminRoles,
            true
        ),
        'one_protected_role_per_user' => $duplicateRoleRows === [],
        'business_permissions_present' => $businessPermissionCount > 0,
        'administration_permissions_present' =>
            $administrationPermissionCount > 0,
    ];

    $failed = [];
    foreach ($checks as $name => $passed) {
        if (!$passed) {
            $failed[] = $name;
        }
    }

    $result = [
        'schema' => 'DDB_ACCESS_CONTROL_P14_1_LIVE_ACCEPTANCE',
        'captured_at' => date(DATE_ATOM),
        'site_admin' => $siteAdmin,
        'counts' => $counts,
        'role_policies' => [
            'SITE_ADMIN' => $roleMap['SITE_ADMIN'] ?? null,
            'GENERAL_MANAGER' => $roleMap['GENERAL_MANAGER'] ?? null,
        ],
        'permission_summary' => [
            'business' => $businessPermissionCount,
            'settings_security_technical' =>
                $administrationPermissionCount,
        ],
        'users_with_multiple_protected_roles' => $duplicateRoleRows,
        'checks' => $checks,
        'failed' => $failed,
        'status' => $failed === [] ? 'PASS' : 'FAIL',
        'oracle_writes' => 'NONE',
    ];
} catch (Throwable $error) {
    $result = [
        'schema' => 'DDB_ACCESS_CONTROL_P14_1_LIVE_ACCEPTANCE',
        'captured_at' => date(DATE_ATOM),
        'site_admin' => $siteAdmin,
        'status' => 'FAIL',
        'failed' => ['live_execution'],
        'error' => preg_replace(
            '/\s+/',
            ' ',
            (string)$error->getMessage()
        ),
        'oracle_writes' => 'NONE',
    ];
}

$dir = dirname(__DIR__) . '/storage/evidence/access_control';
if (!is_dir($dir) && !mkdir($dir, 0775, true) && !is_dir($dir)) {
    throw new RuntimeException(
        'Cannot create access-control evidence directory.'
    );
}
$file = $dir
    . '/ACCESS_CONTROL_R45_P14_1_LIVE_ACCEPTANCE_'
    . date('Ymd_His')
    . '.json';

file_put_contents(
    $file,
    json_encode($result, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES),
    LOCK_EX
);

echo json_encode(
    $result + ['evidence_file' => $file],
    JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES
), PHP_EOL;

exit(($result['status'] ?? 'FAIL') === 'PASS' ? 0 : 1);
