const fs = require('fs');
const path = require('path');

const root = __dirname;
const read = (file) => fs.readFileSync(path.join(root, file), 'utf8');
const endpoint = read('attachment_download.php');
const functions = read('app/functions.php');
const view = read('ticket_view.php');
const rootHtaccess = read('.htaccess');
const ticketHtaccess = read('uploads/tickets/.htaccess');
const schema = read('baza.sql');

let passed = 0;
let failed = 0;
function check(name, condition) {
    if (condition) {
        passed += 1;
        console.log(`PASS ${name}`);
    } else {
        failed += 1;
        console.error(`FAIL ${name}`);
    }
}

check('endpoint zahteva autentifikaciju', endpoint.indexOf('require_auth()') < endpoint.indexOf('FROM ticket_attachments'));
check('ID mora biti pozitivan integer', endpoint.includes('FILTER_VALIDATE_INT') && endpoint.includes("'min_range' => 1"));
check('ne prihvata file parametar', !endpoint.includes("$_GET['file']") && !endpoint.includes("$_POST['file']"));
check('attachment se učitava iz baze', endpoint.includes('a.id AS attachment_id') && endpoint.includes('WHERE a.id = ?'));
check('upit vezuje attachment za tiket', endpoint.includes('JOIN tickets t ON t.id = a.ticket_id'));
check('ticket ID nema collision sa attachment ID-em', endpoint.includes('a.id AS attachment_id') && endpoint.includes('t.id, t.user_id'));
check('učitan je assigned_to', endpoint.includes('t.assigned_to'));
check('koristi centralni ticket RBAC', endpoint.includes('can_view_ticket($attachment, $user)'));
check('interni prilozi imaju strožu proveru', endpoint.includes('can_manage_ticket($attachment, $user)') && endpoint.includes("['is_internal']"));
check('nedozvoljeni resurs ostaje enumeration-safe 404', endpoint.includes("http_response_code(404)"));
check('nedozvoljeni pokušaj se auditira', endpoint.includes("security_log_event('attachment_download_forbidden'"));
check('stored name ima strogi random format', endpoint.includes("[a-f0-9]{32}") && endpoint.includes("preg_match("));
check('stored name je vezan za bazni ticket ID', endpoint.includes("'ticket-' . (int)$attachment['ticket_id'] . '-'") && endpoint.includes('str_starts_with($storedName, $expectedTicketPrefix)'));
check('upload generiše random fizičko ime', functions.includes("bin2hex(random_bytes(16))"));
check('originalno i stored ime se čuvaju odvojeno', schema.includes('`original_name`') && schema.includes('`stored_name`'));
check('upload koristi serverski finfo', functions.includes('new finfo(FILEINFO_MIME_TYPE)'));
check('upload koristi move_uploaded_file', functions.includes('move_uploaded_file'));
check('download koristi kanonski root', endpoint.includes("realpath(__DIR__ . '/uploads/tickets')"));
check('download kanonizuje ciljnu putanju', endpoint.includes('realpath($uploadRoot . DIRECTORY_SEPARATOR . $storedName)'));
check('download proverava dozvoljeni prefiks', endpoint.includes('str_starts_with($path, $allowedPrefix)'));
check('download zahteva čitljiv običan fajl', endpoint.includes('is_file($path)') && endpoint.includes('is_readable($path)'));
check('download ne otkriva fizičku putanju', !endpoint.includes("exit($path)") && !endpoint.includes("die($path)"));
check('Content-Disposition ostaje attachment', endpoint.includes("Content-Disposition: attachment"));
check('originalno ime se čisti od kontrolnih znakova', endpoint.includes("preg_replace('/[\\x00-\\x1F\\x7F]/'"));
check('postavljen je Content-Length', endpoint.includes("Content-Length:"));
check('postavljen je nosniff', endpoint.includes('X-Content-Type-Options: nosniff'));
check('privatni odgovor se ne kešira', endpoint.includes('Cache-Control: private, no-store'));
check('frontend koristi attachment ID endpoint', view.includes("attachment_download.php?id="));
check('frontend nema direktan uploads/tickets href', !/href\s*=\s*["'][^"']*uploads\/tickets/i.test(view));
check('root Apache pravilo blokira ticket uploads', /RewriteRule\s+\^uploads\/tickets\(\?:\/\|\$\)\s+-\s+\[F,L,NC\]/.test(rootHtaccess));
check('ticket folder nema listing', /Options\s+-Indexes/.test(ticketHtaccess));
check('Apache 2.4 potpuno odbija HTTP', /Require\s+all\s+denied/.test(ticketHtaccess));
check('Apache 2.2 fallback postoji', /Deny\s+from\s+all/.test(ticketHtaccess));

const uploadDir = path.join(root, 'uploads', 'tickets');
const legacyFiles = fs.readdirSync(uploadDir).filter((name) => name !== '.htaccess');
check('postojeći attachment fajlovi su sačuvani', legacyFiles.length > 0);
check('postojeći fajlovi prate bezbedan stored format', legacyFiles.every((name) => /^ticket-[0-9]+-[a-f0-9]{32}\.(jpg|jpeg|png|pdf|xls|xlsx|txt)$/.test(name)));
check('postojeći DB zapisi mapiraju se na disk', legacyFiles.every((name) => schema.includes(`'${name}'`)));

console.log(`\nAttachment access control QA: ${passed} passed, ${failed} failed`);
process.exit(failed === 0 ? 0 : 1);
