<?php
// =============================================================================
// codec.php — PHP port of body_envelope_codec.py
//
// Decodes and encodes the t2.g "envelope" format used by panel POST
// endpoints. Wire format:
//     POST body = {"data": "<envelope>"}
//     envelope  = salt_wrap( b64(inner_json) with garbage inserted + 2 markers )
// =============================================================================

if (!defined('PANEL_BASE62_ALPHABET')) {
    define('PANEL_BASE62_ALPHABET',
        'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890');
    define('PANEL_SALT_LEAD', 'jI9NanD1ro8id');
    define('PANEL_SALT_TAIL', 'Gold4Ibo1pRo0');
}

function salt_wrap($s) {
    $n = strlen($s);
    if ($n >= 6) {
        return substr($s, 0, 3) . PANEL_SALT_LEAD . substr($s, 3, $n - 6) . PANEL_SALT_TAIL . substr($s, $n - 3);
    } elseif ($n >= 3) {
        return substr($s, 0, 3) . PANEL_SALT_LEAD . substr($s, 3);
    }
    return $s . PANEL_SALT_TAIL;
}

function salt_unwrap($s) {
    $lead_pos = strpos($s, PANEL_SALT_LEAD);
    if ($lead_pos !== false) {
        $s = substr($s, 0, $lead_pos) . substr($s, $lead_pos + strlen(PANEL_SALT_LEAD));
    }
    $tail_pos = strpos($s, PANEL_SALT_TAIL);
    if ($tail_pos !== false) {
        $s = substr($s, 0, $tail_pos) . substr($s, $tail_pos + strlen(PANEL_SALT_TAIL));
    }
    return $s;
}

function decode_envelope($envelope) {
    if (!is_string($envelope) || strlen($envelope) < 2) {
        return null;
    }
    $s = salt_unwrap($envelope);
    if (strlen($s) < 2) {
        return null;
    }
    $alpha = PANEL_BASE62_ALPHABET;
    $pos_char = $s[strlen($s) - 2];
    $n_char   = $s[strlen($s) - 1];
    $pos       = strpos($alpha, $pos_char);
    $n_garbage = strpos($alpha, $n_char);
    if ($pos === false || $n_garbage === false) {
        return null;
    }
    $s = substr($s, 0, strlen($s) - 2);
    if ($n_garbage > 0) {
        $s = substr($s, 0, $pos) . substr($s, $pos + $n_garbage);
    }
    $raw = base64_decode($s, true);
    if ($raw === false) {
        return null;
    }
    $obj = json_decode($raw, true);
    return is_array($obj) ? $obj : null;
}

function encode_envelope($inner) {
    $json = json_encode($inner, JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE);
    $b64 = trim(base64_encode($json));
    $n_garbage = random_int(0, 19);
    $pos = min(random_int(0, strlen($b64)), 42);
    $alpha = PANEL_BASE62_ALPHABET;
    $alpha_len = strlen($alpha);
    $garbage = '';
    for ($i = 0; $i < $n_garbage; $i++) {
        $garbage .= $alpha[random_int(0, $alpha_len - 1)];
    }
    $b64_obf = substr($b64, 0, $pos) . $garbage . substr($b64, $pos);
    $marker = $alpha[$pos] . $alpha[$n_garbage];
    return salt_wrap($b64_obf . $marker);
}
