<?php

require_once dirname(__DIR__) . '/db_bootstrap.php';

$conn = ensure_db(true);
$instanceId = 'branch_gate_test_' . bin2hex(random_bytes(6));
$secret = 'branch-gate-secret-' . bin2hex(random_bytes(16));
$deviceId = bin2hex(random_bytes(32));
$deviceSecret = bin2hex(random_bytes(32));
$endpoint = 'http://127.0.0.1:8080/mikrotik/admin/api/link_register.php';
$payload = [
    'instance_id' => $instanceId,
    'secret' => $secret,
    'device_id' => $deviceId,
    'device_secret' => $deviceSecret,
    'install_type' => 'branch',
    'instance_name' => 'Branch Approval Gate Test',
    'server_url' => 'http://127.0.0.1:8080/',
    'reported_url' => '',
    'client_platform' => 'windows',
    'connection_mode' => 'local',
    'version' => 'test',
    'build' => 'branch-approval-http-test',
];

function branch_gate_post(string $endpoint, array $payload): array
{
    $context = stream_context_create([
        'http' => [
            'method' => 'POST',
            'header' => "Content-Type: application/x-www-form-urlencoded\r\nAccept: application/json\r\n",
            'content' => http_build_query($payload, '', '&', PHP_QUERY_RFC3986),
            'timeout' => 10,
            'ignore_errors' => true,
        ],
    ]);
    $raw = @file_get_contents($endpoint, false, $context);
    $decoded = is_string($raw) ? json_decode($raw, true) : null;
    if (!is_array($decoded)) {
        throw new RuntimeException('Link API did not return a JSON response.');
    }
    return $decoded;
}

try {
    $pending = branch_gate_post($endpoint, $payload);
    if (($pending['status'] ?? '') !== 'pending') {
        throw new RuntimeException('A new branch request bypassed the pending approval state.');
    }
    if (($pending['portal_url'] ?? '') !== 'http://127.0.0.1:8080/mikrotik/admin') {
        throw new RuntimeException('The branch portal URL was not normalized to the application admin path.');
    }

    $instanceEsc = $conn->real_escape_string($instanceId);
    if (!$conn->query("UPDATE ua_link_requests SET status='approved', approved_at=NOW() WHERE instance_id='{$instanceEsc}'")) {
        throw new RuntimeException('Could not approve the branch test request.');
    }
    $approved = branch_gate_post($endpoint, $payload);
    if (($approved['status'] ?? '') !== 'approved') {
        throw new RuntimeException('An approved branch request was not allowed.');
    }

    $approvedRequestId = (int)($approved['request_id'] ?? 0);
    $reinstallInstanceId = 'branch_gate_reinstall_' . bin2hex(random_bytes(6));
    $reinstallPayload = $payload;
    $reinstallPayload['instance_id'] = $reinstallInstanceId;
    $reinstallPayload['secret'] = 'branch-reinstall-secret-' . bin2hex(random_bytes(16));
    $reinstallPayload['instance_name'] = 'Branch Approval Gate Test Reinstalled';
    $remembered = branch_gate_post($endpoint, $reinstallPayload);
    if (($remembered['status'] ?? '') !== 'approved'
        || empty($remembered['remembered_device'])
        || (int)($remembered['request_id'] ?? 0) !== $approvedRequestId) {
        throw new RuntimeException('A reinstalled known device was not reused and approved automatically.');
    }

    $deviceIdHash = hash('sha256', $deviceId);
    $deviceSecretHash = hash('sha256', $deviceSecret);
    $deviceIdEsc = $conn->real_escape_string($deviceIdHash);
    $deviceSecretEsc = $conn->real_escape_string($deviceSecretHash);
    $sameDevice = $conn->query("SELECT COUNT(*) AS c FROM ua_link_requests WHERE device_id_hash='{$deviceIdEsc}' AND device_secret_hash='{$deviceSecretEsc}' AND install_type='branch'");
    if (!$sameDevice || (int)$sameDevice->fetch_assoc()['c'] !== 1) {
        throw new RuntimeException('The reinstall created a duplicate row for the same device.');
    }

    $reinstallEsc = $conn->real_escape_string($reinstallInstanceId);
    if (!$conn->query("UPDATE ua_link_requests SET status='blocked', approved_at=NULL WHERE instance_id='{$reinstallEsc}'")) {
        throw new RuntimeException('Could not block the branch test request.');
    }
    $blocked = branch_gate_post($endpoint, $reinstallPayload);
    if (($blocked['status'] ?? '') !== 'blocked') {
        throw new RuntimeException('A blocked branch request bypassed the approval gate.');
    }

    if (!$conn->query("DELETE FROM ua_link_requests WHERE instance_id='{$reinstallEsc}'")) {
        throw new RuntimeException('Could not remove the branch approval test request.');
    }
    $left = $conn->query("SELECT COUNT(*) AS c FROM ua_link_requests WHERE instance_id='{$reinstallEsc}'");
    if (!$left || (int)$left->fetch_assoc()['c'] !== 0) {
        throw new RuntimeException('The branch approval test request was not cleaned up.');
    }

    echo json_encode([
        'ok' => true,
        'new_request' => $pending['status'],
        'after_approval' => $approved['status'],
        'reinstall_auto_approval' => $remembered['status'],
        'same_request_id' => (int)$remembered['request_id'],
        'device_rows' => 1,
        'after_block' => $blocked['status'],
        'cleanup' => true,
    ], JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT) . PHP_EOL;
} finally {
    if (isset($instanceEsc)) {
        @$conn->query("DELETE FROM ua_link_requests WHERE instance_id='{$instanceEsc}'");
    }
    if (isset($reinstallEsc)) {
        @$conn->query("DELETE FROM ua_link_requests WHERE instance_id='{$reinstallEsc}'");
    }
    if (isset($deviceIdEsc) && isset($deviceSecretEsc)) {
        @$conn->query("DELETE FROM ua_link_requests WHERE device_id_hash='{$deviceIdEsc}' AND device_secret_hash='{$deviceSecretEsc}'");
    }
}
