VulnerabilityMerger.kt

package com.depanalyzer.repository

import com.depanalyzer.report.Vulnerability
import com.depanalyzer.report.VulnerabilitySeverity
import com.depanalyzer.report.VulnerabilitySource

object VulnerabilityMerger {

    fun mergeVulnerabilities(
        ossIndexVulns: Map<String, List<Vulnerability>>,
        nvdVulns: Map<String, List<Vulnerability>>
    ): Map<String, List<Vulnerability>> {

        val mergedByCveId = mutableMapOf<String, Vulnerability>()

        ossIndexVulns.values.flatten().forEach { vuln ->
            mergedByCveId[vuln.cveId] = vuln
        }

        nvdVulns.values.flatten().forEach { nvdVuln ->
            val cveId = nvdVuln.cveId

            if (cveId in mergedByCveId) {
                val existing = mergedByCveId[cveId]!!

                val mergedScore = nvdVuln.cvssScore ?: existing.cvssScore
                val mergedSeverity = if (mergedScore != null) {
                    VulnerabilitySeverity.fromCvssScore(mergedScore)
                } else {
                    existing.severity
                }

                mergedByCveId[cveId] = existing.copy(
                    cvssScore = mergedScore,
                    severity = mergedSeverity,
                    source = VulnerabilitySource.BOTH,
                    referenceUrl = nvdVuln.referenceUrl ?: existing.referenceUrl,
                    description = nvdVuln.description ?: existing.description
                )
            } else {
                mergedByCveId[cveId] = nvdVuln.copy(source = VulnerabilitySource.NVD)
            }
        }

        val result = mutableMapOf<String, List<Vulnerability>>()

        ossIndexVulns.keys.forEach { key ->
            result[key] = emptyList()
        }

        nvdVulns.keys.forEach { key ->
            result[key] = emptyList()
        }

        mergedByCveId.values
            .groupBy { "${it.affectedDependency.groupId}:${it.affectedDependency.artifactId}:${it.affectedDependency.version}" }
            .forEach { (key, vulns) ->
                result[key] = vulns
            }

        return result
    }
}