VulnerabilityChain.kt

package com.depanalyzer.core.graph

import com.depanalyzer.report.Vulnerability
import com.fasterxml.jackson.annotation.JsonInclude

enum class VulnerabilityClassification {
    DIRECTLY_VULNERABLE,

    INDIRECTLY_VULNERABLE,

    TRANSITIVE_VULNERABLE
}

@JsonInclude(JsonInclude.Include.NON_NULL)
data class VulnerabilityChain(
    val chain: List<DependencyNode>,
    val vulnerabilities: List<Vulnerability>,
    val isShortestPath: Boolean = false,
    val classification: VulnerabilityClassification = VulnerabilityClassification.TRANSITIVE_VULNERABLE
) {

    init {
        require(chain.isNotEmpty()) { "Chain debe contener al menos un nodo" }
        require(vulnerabilities.isNotEmpty()) { "Chain debe contener al menos una vulnerabilidad" }
    }

    val directDependency: DependencyNode
        get() = chain.first()

    val vulnerableNode: DependencyNode
        get() = chain.last()

    val depth: Int
        get() = chain.size - 1

    val cveIds: List<String>
        get() = vulnerabilities.map { it.cveId }

    fun formatAsDetailedPath(): String {
        val pathStr = chain.joinToString(" → ") { it.coordinate }
        val cveStr = cveIds.joinToString(", ")
        return "$pathStr [$cveStr]"
    }

    override fun toString(): String = formatAsDetailedPath()
}