// ide-extension-data.mjs — Loads top-extensions + blocklist from knowledge files.
// Zero dependencies (Node.js builtins only).
// Used by ide-extension-scanner.mjs for typosquat + blocklist checks.

import { readFile } from 'node:fs/promises';
import { join, dirname } from 'node:path';
import { fileURLToPath } from 'node:url';

const __dirname = dirname(fileURLToPath(import.meta.url));
const KNOWLEDGE_DIR = join(__dirname, '..', '..', 'knowledge');

let _vscode = null;
let _jetbrains = null;

async function loadJson(path) {
  try {
    const raw = await readFile(path, 'utf8');
    return JSON.parse(raw);
  } catch {
    return null;
  }
}

/**
 * Load top VS Code extension IDs.
 * @returns {Promise<string[]>} Lowercased "publisher.name" strings.
 */
export async function loadTopVSCode() {
  if (_vscode !== null) return _vscode.vscode || [];
  _vscode = await loadJson(join(KNOWLEDGE_DIR, 'top-vscode-extensions.json')) || { vscode: [], blocklist: [] };
  return (_vscode.vscode || []).map(normalizeId);
}

/**
 * Load VS Code extension blocklist entries.
 * @returns {Promise<string[]>} Entries of form "publisher.name@version" or "publisher.name@*".
 */
export async function loadVSCodeBlocklist() {
  if (_vscode !== null) return _vscode.blocklist || [];
  _vscode = await loadJson(join(KNOWLEDGE_DIR, 'top-vscode-extensions.json')) || { vscode: [], blocklist: [] };
  return _vscode.blocklist || [];
}

/**
 * Load top JetBrains plugin xmlIds (canonical corpus for typosquat detection).
 * @returns {Promise<string[]>} Lowercased xmlIds.
 */
export async function loadTopJetBrains() {
  if (_jetbrains !== null) return (_jetbrains.jetbrains || []).map(normalizeId);
  _jetbrains = await loadJson(join(KNOWLEDGE_DIR, 'top-jetbrains-plugins.json')) || { jetbrains: [], blocklist: [] };
  return (_jetbrains.jetbrains || []).map(normalizeId);
}

/**
 * Load JetBrains plugin blocklist entries.
 * Empty by design — no public confirmed-malicious JetBrains Marketplace plugins
 * as of 2026-04-17. Enterprise policy.json can seed private entries.
 * @returns {Promise<string[]>} Entries of form "xmlId@version" or "xmlId@*".
 */
export async function loadJetBrainsBlocklist() {
  if (_jetbrains !== null) return _jetbrains.blocklist || [];
  _jetbrains = await loadJson(join(KNOWLEDGE_DIR, 'top-jetbrains-plugins.json')) || { jetbrains: [], blocklist: [] };
  return _jetbrains.blocklist || [];
}

/**
 * Normalize extension ID for comparison.
 * @param {string} id
 * @returns {string}
 */
export function normalizeId(id) {
  return String(id || '').toLowerCase().trim();
}

/**
 * Reset cache (for tests).
 */
export function _resetCache() {
  _vscode = null;
  _jetbrains = null;
}
