/**
 * SARIF Upload - GitHub Code Scanning Integration
 *
 * Uploads SARIF files to GitHub Code Scanning API.
 *
 * @module action/sarif-upload
 */
import { readFile, writeFile } from "fs/promises";
import { gzipSync } from "zlib";
import { join } from "path";
/**
 * Convert aggregated scan results to SARIF format
 */
export function convertToSarif(scanResult) {
    const rules = new Map();
    const results = [];
    for (const scanner of scanResult.scanners) {
        for (const finding of scanner.findings) {
            // Add rule if not already present
            if (!rules.has(finding.ruleId)) {
                rules.set(finding.ruleId, {
                    id: finding.ruleId,
                    name: finding.ruleId.split(":").pop() || finding.ruleId,
                    shortDescription: { text: finding.message.slice(0, 100) },
                    fullDescription: { text: finding.message },
                    defaultConfiguration: {
                        level: severityToSarifLevel(finding.severity),
                    },
                    properties: {
                        tags: [finding.scanner, finding.severity],
                        "security-severity": severityToScore(finding.severity),
                    },
                });
            }
            // Add result
            results.push({
                ruleId: finding.ruleId,
                level: severityToSarifLevel(finding.severity),
                message: { text: finding.message },
                locations: [
                    {
                        physicalLocation: {
                            artifactLocation: {
                                uri: finding.file,
                                uriBaseId: "%SRCROOT%",
                            },
                            region: {
                                startLine: finding.line,
                                startColumn: finding.column,
                                endLine: finding.endLine,
                                endColumn: finding.endColumn,
                            },
                        },
                    },
                ],
                fingerprints: {
                    primaryLocationLineHash: generateFingerprint(finding),
                },
            });
        }
    }
    return {
        $schema: "https://raw.githubusercontent.com/oasis-tcs/sarif-spec/master/Schemata/sarif-schema-2.1.0.json",
        version: "2.1.0",
        runs: [
            {
                tool: {
                    driver: {
                        name: "Vaspera Hardening",
                        version: "1.0.0",
                        informationUri: "https://github.com/RCOLKITT/hardening-mcp",
                        rules: Array.from(rules.values()),
                    },
                },
                results,
                automationDetails: {
                    id: `vaspera-hardening/${scanResult.timestamp}`,
                },
            },
        ],
    };
}
/**
 * Convert severity to SARIF level
 */
function severityToSarifLevel(severity) {
    switch (severity) {
        case "critical":
        case "high":
            return "error";
        case "medium":
            return "warning";
        case "low":
        case "info":
            return "note";
        default:
            return "note";
    }
}
/**
 * Convert severity to security-severity score
 */
function severityToScore(severity) {
    switch (severity) {
        case "critical":
            return "9.0";
        case "high":
            return "7.0";
        case "medium":
            return "4.0";
        case "low":
            return "2.0";
        case "info":
            return "0.0";
        default:
            return "0.0";
    }
}
/**
 * Generate a fingerprint for deduplication
 */
function generateFingerprint(finding) {
    const data = `${finding.ruleId}:${finding.file}:${finding.line}:${finding.message.slice(0, 50)}`;
    // Simple hash - in production use crypto
    let hash = 0;
    for (let i = 0; i < data.length; i++) {
        const char = data.charCodeAt(i);
        hash = (hash << 5) - hash + char;
        hash = hash & hash; // Convert to 32-bit integer
    }
    return Math.abs(hash).toString(16).padStart(8, "0");
}
/**
 * Write SARIF file to disk
 */
export async function writeSarifFile(sarif, outputPath) {
    const content = JSON.stringify(sarif, null, 2);
    await writeFile(outputPath, content, "utf-8");
    return outputPath;
}
/**
 * Upload SARIF to GitHub Code Scanning API
 *
 * Note: This requires the code-scanning: write permission
 */
export async function uploadSarifToGitHub(
// eslint-disable-next-line @typescript-eslint/no-explicit-any
octokit, context, sarifPath) {
    // Read and compress SARIF
    const sarifContent = await readFile(sarifPath, "utf-8");
    const compressed = gzipSync(sarifContent);
    const base64Sarif = compressed.toString("base64");
    // Upload to GitHub
    const response = await octokit.rest.codeScanning.uploadSarif({
        owner: context.owner,
        repo: context.repo,
        commit_sha: context.sha,
        ref: context.ref,
        sarif: base64Sarif,
        tool_name: "Vaspera Hardening",
    });
    return { id: response.data.id || "unknown" };
}
/**
 * Generate SARIF file path
 */
export function getSarifFilePath(workingDirectory) {
    return join(workingDirectory, "vaspera-results.sarif");
}
/**
 * Check if SARIF upload is supported (requires write permission)
 */
export async function checkSarifUploadSupported(
// eslint-disable-next-line @typescript-eslint/no-explicit-any
octokit, context) {
    try {
        const response = await octokit.rest.repos.get({
            owner: context.owner,
            repo: context.repo,
        });
        // Check if we have push permission (implies code-scanning write)
        return response.data.permissions?.push === true;
    }
    catch {
        return false;
    }
}
//# sourceMappingURL=sarif-upload.js.map