/**
 * decode-guest.js — QuickJS-compatible decode implementation for Extism WASM sandbox.
 *
 * Ports the decode logic from cli/lib/tools/recon.js to run inside an Extism
 * WASM plugin (QuickJS runtime). No Node.js APIs (Buffer, process, etc.) are
 * available. Uses atob() for base64 and manual conversion for hex.
 *
 * Input:  JSON string { "data": "...", "encoding": "auto"|"base64"|"hex"|"url"|"jwt" }
 * Output: JSON string { "input": "...", "results": [...] }
 *
 * Compiled with: extism-js decode-guest.js -i decode-guest.d.ts -o decode.wasm
 */

// Extism PDK globals: Host.inputString(), Host.outputString()

function tryDecodeBase64(data) {
  var cleaned = data.trim();
  // Must look like base64 (A-Za-z0-9+/= or URL-safe variant)
  if (!/^[A-Za-z0-9+/=_-]{4,}$/.test(cleaned)) return null;
  try {
    // Convert URL-safe base64 to standard base64
    var std = cleaned.replace(/-/g, '+').replace(/_/g, '/');
    // Pad if needed
    while (std.length % 4 !== 0) std += '=';
    var decoded = atob(std);
    // Verify it decoded to something printable
    if (decoded.length > 0 && /^[\x20-\x7e\n\r\t]+$/.test(decoded)) {
      return decoded;
    }
  } catch (e) { /* not base64 */ }
  return null;
}

function tryDecodeHex(data) {
  var cleaned = data.trim().replace(/^0x/i, '').replace(/\s+/g, '');
  if (!/^[0-9a-fA-F]{4,}$/.test(cleaned) || cleaned.length % 2 !== 0) return null;
  try {
    var decoded = '';
    for (var i = 0; i < cleaned.length; i += 2) {
      decoded += String.fromCharCode(parseInt(cleaned.substr(i, 2), 16));
    }
    if (decoded.length > 0 && /^[\x20-\x7e\n\r\t]+$/.test(decoded)) {
      return decoded;
    }
  } catch (e) { /* not hex */ }
  return null;
}

function tryDecodeURL(data) {
  if (data.indexOf('%') === -1) return null;
  try {
    var decoded = decodeURIComponent(data);
    if (decoded !== data) return decoded;
  } catch (e) { /* not URL encoded */ }
  return null;
}

function tryDecodeJWT(data) {
  var parts = data.trim().split('.');
  if (parts.length !== 3) return null;
  try {
    // base64url decode for JWT parts
    function b64urlDecode(str) {
      var s = str.replace(/-/g, '+').replace(/_/g, '/');
      while (s.length % 4 !== 0) s += '=';
      return atob(s);
    }
    var header = JSON.parse(b64urlDecode(parts[0]));
    var payload = JSON.parse(b64urlDecode(parts[1]));
    return {
      header: header,
      payload: payload,
      signature: parts[2].slice(0, 20) + '...',
      expiresAt: payload.exp ? new Date(payload.exp * 1000).toISOString() : null,
    };
  } catch (e) { /* not JWT */ }
  return null;
}

function decode() {
  var inputStr = Host.inputString();
  var input;
  try {
    input = JSON.parse(inputStr);
  } catch (e) {
    Host.outputString(JSON.stringify({ error: 'Invalid JSON input: ' + e.message }));
    return 0;
  }

  var data = input.data;
  var encoding = input.encoding || 'auto';

  if (!data || typeof data !== 'string') {
    Host.outputString(JSON.stringify({ error: 'data is required (string)' }));
    return 0;
  }

  var results = [];

  if (encoding === 'auto' || encoding === 'jwt') {
    var jwt = tryDecodeJWT(data);
    if (jwt) results.push({ encoding: 'jwt', decoded: jwt });
  }

  if (encoding === 'auto' || encoding === 'base64') {
    var b64 = tryDecodeBase64(data);
    if (b64) results.push({ encoding: 'base64', decoded: b64 });
  }

  if (encoding === 'auto' || encoding === 'hex') {
    var hex = tryDecodeHex(data);
    if (hex) results.push({ encoding: 'hex', decoded: hex });
  }

  if (encoding === 'auto' || encoding === 'url') {
    var url = tryDecodeURL(data);
    if (url) results.push({ encoding: 'url', decoded: url });
  }

  var output = {
    input: data.slice(0, 200),
    results: results.length > 0 ? results : [{ encoding: 'none', decoded: 'No valid encoding detected' }],
  };

  Host.outputString(JSON.stringify(output));
  return 0;
}

module.exports = { decode };
