//! Vulnerabilities represent the intersection of the [`Advisory`] database
//! and a particular `Cargo.lock` file.

use crate::{
    advisory::{self, affected::FunctionPath, Advisory},
    package::Package,
};
use serde::{Deserialize, Serialize};

/// A vulnerable package and the associated advisory
#[derive(Clone, Debug, Deserialize, Eq, PartialEq, Serialize)]
pub struct Vulnerability {
    /// Security advisory for which the package is vulnerable
    pub advisory: advisory::Metadata,

    /// Versions impacted by this vulnerability
    pub versions: advisory::Versions,

    /// More specific information about what this advisory affects (if available)
    pub affected: Option<advisory::Affected>,

    /// Vulnerable package
    pub package: Package,
}

impl Vulnerability {
    /// Create `Vulnerability` about a given [`Advisory`] and [`Package`]
    pub fn new(advisory: &Advisory, package: &Package) -> Self {
        Self {
            advisory: advisory.metadata.clone(),
            versions: advisory.versions.clone(),
            affected: advisory.affected.clone(),
            package: package.clone(),
        }
    }

    /// Get the set of functions affected by this vulnerability (if available)
    pub fn affected_functions(&self) -> Option<Vec<FunctionPath>> {
        self.affected.as_ref().and_then(|affected| {
            if affected.functions.is_empty() {
                None
            } else {
                let mut result = vec![];
                for (path, versions) in &affected.functions {
                    if versions
                        .iter()
                        .any(|req| req.matches(&self.package.version.clone()))
                    {
                        result.push(path.clone());
                    }
                }
                Some(result)
            }
        })
    }
}
