#!/bin/bash
set -euo pipefail

images=(
    "docker.io/bitnami/redis-exporter@sha256:1be8423b10c65424f5ad0464110061f1f265bca32fed442688e7bc7cd1433d53"
    "docker.io/bitnami/redis-cluster@sha256:7d56f7e9e2ec01a376bc847fa0a16b48daf87e754f011735aa81249bb050ceb2"
    "docker.io/bitnami/mongodb@sha256:8683a10d1e24dcb1053913f6e6acaa8b64001788b76ee8ccb2cd46149e4b50a3"
    "docker.io/bitnami/external-dns@sha256:2b91adec6a5b8c71bfe2a8fbbf38074af0f31d55824a8e37778be94b46a715ee"
    "docker.io/bitnami/redis@sha256:b3f30979f2d1d00a1885ea8cbd8c91c24b5884f9da5b8ff9f7a7ac07ecbff371"
    "quay.io/spotahome/redis-operator@sha256:ce8391214b906d8c776269c8eff04b69de426ba1c0ff3e227ae682993ba8ee2e"
    "docker.io/amazon/aws-efs-csi-driver@sha256:a5d6d98529e1c9ac402de1e922c879b2e6c36a1a9e0a79a731148ce35446f2eb"
    "docker.io/amazon/aws-efs-csi-driver@sha256:a5d6d98529e1c9ac402de1e922c879b2e6c36a1a9e0a79a731148ce35446f2eb"
)

# Update with your API Key
nvd_api_key="'"
nvd_base_url="https://services.nvd.nist.gov/rest/json/cves/2.0"
out_dir="nvd"
mkdir -p "$out_dir"

# ---- Helper: sanitize a string for filenames ----
sanitize() {
  echo "$1" | tr '/:@' '___' | tr -cd 'A-Za-z0-9._-'
}

for image in "${images[@]}"; do
  # Ensure tag
  [[ "$image" != *:* ]] && image="${image}:latest"

  echo ""
  echo "Scanning image: $image"

  # Pull (fail on error)
  docker pull "$image" >/dev/null

  # Save grype JSON
  img_tag_sane="$(sanitize "$image")"
  grype_json_path="${out_dir}/grype_${img_tag_sane}.json"

#   echo "-> Running grype and saving JSON: ${grype_json_path}"
  grype_json="$(grype "$image" -o json 2>/dev/null || true)"
  echo "${grype_json}" > "${grype_json_path}"

  # Extract unique CVE IDs (only HIGH or CRITICAL severities)
  mapfile -t cves < <(echo "${grype_json}" | jq -r '
  .matches[]?
  | select((.vulnerability.severity | ascii_upcase) == "HIGH" or (.vulnerability.severity | ascii_upcase) == "CRITICAL")
  | .vulnerability.id
  | select(startswith("CVE-"))
' | sort -u)

  if [[ ${#cves[@]} -eq 0 ]]; then
    echo "-> No CVEs found in grype results."
    continue
  fi

#   echo "-> Found ${#cves[@]} unique Critical or High CVE(s). Fetching NVD JSON…"

  for cve in "${cves[@]}"; do
    
    if [[ "$cve" == CVE-* ]]; then
        mkdir -p "$out_dir/cves"
        api_url="$nvd_base_url?cveId=$cve"
        http_code=$(curl -sS -H "Accept: application/json" -H "apiKey: $nvd_api_key" -o "$out_dir/cves/$cve.json" -w "%{http_code}" "$api_url")
        
         # Retry while HTTP code is 429
        while [[ "$http_code" -eq 429 ]]; do
            # echo "Rate limited (429) for $cve. Waiting 10 seconds before retrying..."
            sleep 10
            http_code=$(curl -sS -H "Accept: application/json" \
                             -H "apiKey: $nvd_api_key" \
                             -o "$out_dir/cves/$cve.json" \
                             -w "%{http_code}" "$api_url")
        done

        if [[ "$http_code" -ne 200 ]]; then
            echo "NVD request failed (HTTP $http_code) for $api_url"
            exit 1
        fi
        cisaExploitAdd=$(jq -r '.vulnerabilities[].cve.cisaExploitAdd // empty' "$out_dir/cves/$cve.json")
        cisaActionDue=$(jq -r '.vulnerabilities[].cve.cisaActionDue // empty' "$out_dir/cves/$cve.json")
        cisaRequiredAction=$(jq -r '.vulnerabilities[].cve.cisaRequiredAction // empty' "$out_dir/cves/$cve.json")
        cisaVulnerabilityName=$(jq -r '.vulnerabilities[].cve.cisaVulnerabilityName // empty' "$out_dir/cves/$cve.json")

        # If any CISA KEV fields exist, print details
        if [[ -n "$cisaExploitAdd" || -n "$cisaActionDue" || -n "$cisaRequiredAction" || -n "$cisaVulnerabilityName" ]]; then

            baseScore=$(jq -r '
                .vulnerabilities[].cve.metrics.cvssMetricV31[0]?.cvssData.baseScore
                // .vulnerabilities[].cve.metrics.cvssMetricV30[0]?.cvssData.baseScore
                // .vulnerabilities[].cve.metrics.cvssMetricV2[0]?.cvssData.baseScore
                // "N/A"
            ' "$out_dir/cves/$cve.json")

            baseSeverity=$(jq -r '
                .vulnerabilities[].cve.metrics.cvssMetricV31[0]?.cvssData.baseSeverity
                // .vulnerabilities[].cve.metrics.cvssMetricV30[0]?.cvssData.baseSeverity
                // .vulnerabilities[].cve.metrics.cvssMetricV2[0]?.baseSeverity
                // "N/A"
            ' "$out_dir/cves/$cve.json")
        
            echo ""
            echo "**************"
            echo "Container image: $image"
            echo "CVE Found with CISA KEV"
            echo "CVE ID: $cve"
            echo "Base Score: $baseScore"
            echo "Base Severity: $baseSeverity"
            echo "CISA Exploit Add: $cisaExploitAdd"
            echo "CISA Action Due: $cisaActionDue"
            echo "CISA Required Action: $cisaRequiredAction"
            echo "CISA Vulnerability Name: $cisaVulnerabilityName"
            echo "**************"
            echo ""
            
        fi
    fi
  done
done

echo ""
echo "Done. Outputs saved under: ${out_dir}/"
