/**
 * Report formatters (HTML + Markdown) for audit results.
 * HTML: single-file with inline CSS. Markdown: clean tables.
 */
// CodeQL suppression: shell embedding in fixCommand is display-only;
// commands are shown to users but never executed
/** Escape HTML entities */
function escapeHtml(str) {
    return str
        .replace(/&/g, "&amp;")
        .replace(/</g, "&lt;")
        .replace(/>/g, "&gt;")
        .replace(/"/g, "&quot;");
}
/** Score color for HTML */
function scoreColorHtml(score) {
    if (score >= 80)
        return "#2d7d46";
    if (score >= 60)
        return "#b58900";
    return "#dc3545";
}
/** Status icon for HTML */
function statusIcon(passed) {
    return passed ? "&#x2705;" : "&#x274C;";
}
/**
 * Format audit result as self-contained HTML report.
 */
export function formatHtmlReport(result) {
    const categoryRows = result.categories
        .map((cat) => {
        const checkRows = cat.checks
            .map((check) => `
          <tr>
            <td>${statusIcon(check.passed)}</td>
            <td>${escapeHtml(check.id)}</td>
            <td>${escapeHtml(check.name)}</td>
            <td><span class="severity severity-${check.severity}">${check.severity}</span></td>
            <td>${escapeHtml(check.currentValue)}</td>
            <td>${escapeHtml(check.expectedValue)}</td>
            <td>${check.fixCommand ? `<code>${escapeHtml(check.fixCommand)}</code>` : "-"}</td>
          </tr>`)
            .join("\n");
        return `
      <div class="category">
        <h2>${escapeHtml(cat.name)} <span class="score" style="color: ${scoreColorHtml(cat.score)}">${cat.score}/${cat.maxScore}</span></h2>
        <table>
          <thead>
            <tr>
              <th></th><th>ID</th><th>Check</th><th>Severity</th><th>Current</th><th>Expected</th><th>Fix</th>
            </tr>
          </thead>
          <tbody>
            ${checkRows}
          </tbody>
        </table>
      </div>`;
    })
        .join("\n");
    const quickWinsHtml = result.quickWins.length > 0
        ? `
    <div class="quick-wins">
      <h2>Quick Wins</h2>
      <p>Run these commands to improve your score:</p>
      <ul>
        ${result.quickWins.map((w) => `<li>${escapeHtml(w.description)}<br><code>${w.commands.map(escapeHtml).join(" && ")}</code></li>`).join("\n        ")}
      </ul>
    </div>`
        : "";
    return `<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Kastell Security Audit - ${escapeHtml(result.serverName)}</title>
  <style>
    * { margin: 0; padding: 0; box-sizing: border-box; }
    body { font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif; line-height: 1.6; color: #333; max-width: 900px; margin: 0 auto; padding: 2rem; }
    h1 { margin-bottom: 0.5rem; }
    h2 { margin: 1.5rem 0 0.5rem; }
    .header { border-bottom: 2px solid #eee; padding-bottom: 1rem; margin-bottom: 1.5rem; }
    .overall-score { font-size: 2.5rem; font-weight: bold; }
    .server-info { color: #666; }
    table { width: 100%; border-collapse: collapse; margin: 0.5rem 0 1rem; }
    th, td { padding: 0.5rem; text-align: left; border-bottom: 1px solid #eee; }
    th { background: #f8f9fa; font-weight: 600; }
    .score { font-weight: bold; }
    .severity { padding: 2px 8px; border-radius: 4px; font-size: 0.85rem; color: #fff; }
    .severity-critical { background: #dc3545; }
    .severity-warning { background: #ffc107; color: #333; }
    .severity-info { background: #17a2b8; }
    code { background: #f1f1f1; padding: 2px 6px; border-radius: 3px; font-size: 0.9rem; }
    .quick-wins { background: #f0f9f0; padding: 1rem; border-radius: 8px; margin-top: 1.5rem; }
    .quick-wins ul { padding-left: 1.5rem; }
    .quick-wins li { margin: 0.5rem 0; }
    .footer { margin-top: 2rem; padding-top: 1rem; border-top: 1px solid #eee; color: #999; font-size: 0.85rem; }
  </style>
</head>
<body>
  <div class="header">
    <h1>Security Audit Report</h1>
    <p class="server-info">${escapeHtml(result.serverName)} (${escapeHtml(result.serverIp)}) | Platform: ${escapeHtml(result.platform)}</p>
    <p class="overall-score" style="color: ${scoreColorHtml(result.overallScore)}">${result.overallScore}/100</p>
  </div>

  ${categoryRows}
  ${quickWinsHtml}

  <div class="footer">
    <p>Generated by Kastell | ${escapeHtml(result.timestamp)}</p>
  </div>
</body>
</html>`;
}
/**
 * Format audit result as Markdown report.
 */
export function formatMdReport(result) {
    const lines = [];
    lines.push(`# Security Audit: ${result.serverName} (${result.overallScore}/100)`);
    lines.push("");
    lines.push(`**Server:** ${result.serverName} (${result.serverIp})`);
    lines.push(`**Platform:** ${result.platform}`);
    lines.push(`**Date:** ${result.timestamp}`);
    lines.push(`**Overall Score:** ${result.overallScore}/100`);
    lines.push("");
    for (const category of result.categories) {
        lines.push(`## ${category.name} (${category.score}/${category.maxScore})`);
        lines.push("");
        lines.push("| Check | Severity | Status | Current | Expected | Fix |");
        lines.push("|-------|----------|--------|---------|----------|-----|");
        for (const check of category.checks) {
            const status = check.passed ? "Pass" : "FAIL";
            const fix = check.fixCommand ? `\`${check.fixCommand.replace(/\|/g, "\\|")}\`` : "-";
            lines.push(`| ${check.name} | ${check.severity} | ${status} | ${check.currentValue.replace(/\|/g, "\\|")} | ${check.expectedValue.replace(/\|/g, "\\|")} | ${fix} |`);
        }
        lines.push("");
    }
    if (result.quickWins.length > 0) {
        lines.push("## Quick Wins");
        lines.push("");
        for (const win of result.quickWins) {
            lines.push(`- **${win.description}** (${win.currentScore} -> ${win.projectedScore})`);
            for (const cmd of win.commands) {
                lines.push(`  \`\`\`bash`);
                lines.push(`  ${cmd}`);
                lines.push(`  \`\`\``);
            }
        }
        lines.push("");
    }
    lines.push("---");
    lines.push("*Generated by Kastell*");
    lines.push("");
    return lines.join("\n");
}
//# sourceMappingURL=report.js.map