// Code-Injection Signal Providers (v3)
// Typed features for the three high-precision, reliably-observable code-injection
// techniques, ported from the dead xss / html-smuggling / wasm-mining detectors:
//   - reflected XSS payload in a navigation URL query parameter
//   - HTML smuggling: an executable downloaded from a blob:/data: URL
//   - cryptojacking: a request to a known miner library / mining pool
//
// All read target.url (channel 'url'); smuggled_download also reads
// target.filename. The DOM-XSS / eval / postMessage parts of the legacy xss
// detector are NOT ported — they need page-world sink instrumentation and are
// FP-dense (every framework calls innerHTML).

// Reflected-XSS payloads: only unambiguous HTML-injection shapes. The bare
// event-handler regex is omitted (FP on "onsale=" etc.).
const XSS_PAYLOAD = [
  /<script[\s>]/i,
  /<iframe[\s>]/i,
  /<svg[^>]*\son\w+\s*=/i,
  /<img[^>]*\sonerror\s*=/i,
  /<body[^>]*\sonload\s*=/i,
  /javascript:\s*[a-z(]/i,
  /<[a-z]+[^>]*\son(?:error|load|click|mouseover)\s*=\s*["']?[^"'>]/i,
];

// Dangerous (Windows-centric) executable / script extensions for smuggling.
// .js / .sh / .csv / .pdf are intentionally excluded (web apps legitimately
// build and download those from blobs).
const SMUGGLE_EXT = /\.(exe|dll|msi|bat|cmd|ps1|vbs|vbe|scr|hta|jar|iso|img|com|cpl|lnk|jse|wsf|msc|reg)$/i;

// Known cryptojacking libraries / mining pools (blocklist tokens).
const MINER = /\b(coinhive|authedmine|cryptoloot|crypto-loot|coinimp|jsecoin|deepminer|webminerpool|cryptonight|minero\.cc|coin-?have|monerominer|minexmr|nerdpool|webmine\.cz|cpufun|hashvault|moneroocean|crypto-webminer|projectpoi|mine\.torrent)\b/i;
const STRATUM = /(stratum\+tcp|stratum\+ssl|\/proxy\?.*xmr|mining\.subscribe)/i;

function paramsOf(url) {
  try { return new URL(url).searchParams; } catch { return null; }
}

/**
 * @param {import('../../core/signal-provider.js').SignalProviderRegistry} registry
 */
export function registerCodeInjectionSignals(registry) {
  // ── url.xss_payload ───────────────────────────
  // A query parameter value that contains a reflected-XSS HTML/JS payload.
  registry.register('url', 'xss_payload', (target) => {
    const sp = paramsOf(target.url);
    if (!sp) return { value: false };
    for (const [k, v] of sp.entries()) {
      if (!v || v.length < 8) continue;
      let dec = v;
      try { dec = decodeURIComponent(v); } catch {}
      if (XSS_PAYLOAD.some(p => p.test(dec))) {
        return { value: true, metadata: { param: k, sample: dec.slice(0, 80) } };
      }
    }
    return { value: false };
  }, { returnType: 'boolean', scope: 'frame', description: 'Reflected-XSS payload in a URL parameter' });

  // ── url.smuggled_download ─────────────────────
  // An executable/script file downloaded from a client-assembled blob:/data: URL.
  registry.register('url', 'smuggled_download', (target) => {
    const url = target.url || '';
    const isClientAssembled = /^(blob:|data:)/i.test(url);
    if (!isClientAssembled) return { value: false };
    const fn = (target.filename || '').toLowerCase();
    if (SMUGGLE_EXT.test(fn)) {
      return { value: true, metadata: { filename: target.filename, scheme: url.slice(0, 5) } };
    }
    return { value: false };
  }, { returnType: 'boolean', scope: 'frame', description: 'Executable download from a blob:/data: URL (HTML smuggling)' });

  // ── url.miner_resource ────────────────────────
  // A request to a known cryptojacking library or mining pool.
  registry.register('url', 'miner_resource', (target) => {
    const url = target.url || '';
    if (MINER.test(url) || STRATUM.test(url)) {
      return { value: true, metadata: { url: url.slice(0, 120) } };
    }
    return { value: false };
  }, { returnType: 'boolean', scope: 'frame', description: 'Request to a known miner library / mining pool' });
}
