<?php
require_once __DIR__ . '/app/functions.php';

$passed = 0;
$failed = 0;
function qa_org_check(string $label, bool $condition): void
{
    global $passed, $failed;
    if ($condition) {
        $passed++;
        echo "PASS | {$label}\n";
    } else {
        $failed++;
        echo "FAIL | {$label}\n";
    }
}

$userF = ['id' => 10, 'is_system_admin' => 0, 'role_codes' => ['USERF']];
$userDs = ['id' => 20, 'is_system_admin' => 0, 'role_codes' => ['USERDS']];
$ictF = ['id' => 11, 'is_system_admin' => 0, 'role_codes' => ['USERF', 'ICTF']];
$ictDs = ['id' => 21, 'is_system_admin' => 0, 'role_codes' => ['USERDS', 'ICTDS']];
$ambiguous = ['id' => 30, 'is_system_admin' => 0, 'role_codes' => ['USERF', 'USERDS']];

qa_org_check('USERF pripada Fondaciji', role_organization_unit('USERF') === 'F');
qa_org_check('USERDS pripada Dečijem selu', role_organization_unit('USERDS') === 'DS');
qa_org_check('ICTF funkcionalni kod je ICT', role_functional_code('ICTF') === 'ICT');
qa_org_check('ICTDS funkcionalni kod je ICT', role_functional_code('ICTDS') === 'ICT');
qa_org_check('ICTF se mapira na ICTDS za DS', role_code_for_unit('ICTF', 'DS') === 'ICTDS');
qa_org_check('OFCDS se mapira na OFCF za Fondaciju', role_code_for_unit('OFCDS', 'F') === 'OFCF');
qa_org_check('USERF korisnik ima jednoznačnu F pripadnost', user_organization_unit($userF) === 'F');
qa_org_check('USERDS korisnik ima jednoznačnu DS pripadnost', user_organization_unit($userDs) === 'DS');
qa_org_check('USERF + USERDS je namerno neodređena pripadnost', user_organization_unit($ambiguous) === null);
qa_org_check('USERF nije processing uloga', !user_has_additional_role($userF));
qa_org_check('USERDS nije processing uloga', !user_has_additional_role($userDs));
qa_org_check('ICTF jeste processing uloga', user_has_additional_role($ictF));
qa_org_check('ICTDS jeste processing uloga', user_has_additional_role($ictDs));
qa_org_check('USERF može da kreira tiket', can_create_ticket($userF));
qa_org_check('USERDS može da kreira tiket', can_create_ticket($userDs));
qa_org_check('ICT kategorija rutira Fondaciju na ICTF', category_responsible_role_code('ICT oprema', 'F') === 'ICTF');
qa_org_check('ICT kategorija rutira Dečije selo na ICTDS', category_responsible_role_code('ICT oprema', 'DS') === 'ICTDS');
qa_org_check('Vozila rutiraju Dečije selo na VHCDS', category_responsible_role_code('Službena vozila', 'DS') === 'VHCDS');
qa_org_check('Ostalo rutira Dečije selo na OTHDS', category_responsible_role_code('Ostalo', 'DS') === 'OTHDS');
qa_org_check('Ticket unit se čita iz odgovorne role', ticket_organization_unit(['responsible_role_code' => 'OFCDS']) === 'DS');
qa_org_check('F i DS role imaju razumljive prikazne nazive', role_label('ICTF') === 'ICT podrška — Fondacija' && role_label('ICTDS') === 'ICT podrška — Dečije selo');
qa_org_check('Funkcionalni naziv kategorije ne duplira organizacionu jedinicu', functional_role_label('ICTDS') === 'ICT podrška');

[$fAssignedSql, $fAssignedParams] = assigned_tickets_access_sql($ictF);
[$dsAssignedSql, $dsAssignedParams] = assigned_tickets_access_sql($ictDs);
qa_org_check('Assigned resolver koristi tačno poređenje role sa tiketom', str_contains($fAssignedSql, 'r_assigned.role_code = t.responsible_role_code'));
qa_org_check('Assigned resolver isključuje obe osnovne role', $fAssignedParams === [11, 11, 'USERF', 'USERDS'] && $dsAssignedParams === [21, 21, 'USERF', 'USERDS']);

// Nezavisna simulacija exact-role pravila: slična funkcija u drugoj jedinici ne daje pristup.
$canSeeByRole = static fn(array $user, string $ticketRole): bool => in_array($ticketRole, $user['role_codes'], true);
qa_org_check('ICTF ne dobija ICTDS tiket samo zbog iste funkcionalne uloge', !$canSeeByRole($ictF, 'ICTDS'));
qa_org_check('ICTDS ne dobija ICTF tiket samo zbog iste funkcionalne uloge', !$canSeeByRole($ictDs, 'ICTF'));
qa_org_check('ICTF dobija ICTF tiket', $canSeeByRole($ictF, 'ICTF'));
qa_org_check('ICTDS dobija ICTDS tiket', $canSeeByRole($ictDs, 'ICTDS'));

$thrown = false;
try {
    role_code_for_unit('ICTF', 'UNKNOWN');
} catch (InvalidArgumentException $e) {
    $thrown = true;
}
qa_org_check('Nepoznata organizaciona jedinica se odbija', $thrown);

echo "\nRezultat: {$passed}/" . ($passed + $failed) . " runtime provera uspešno.\n";
exit($failed === 0 ? 0 : 1);
