#compdef vulnscan-ai
# zsh completion for vulnscan-ai

_vulnscan-ai() {
  local curcontext="$curcontext" state line
  local -a cmds sev scanners providers
  cmds=(
    'menu:interactive menu covering every command (default with no command)'
    'info:show host/FIPS/GPU/scanner/provider status'
    'scan:scan for vulnerabilities'
    'fix:propose and (with approval) apply fixes'
    'rollback:restore a previously-applied fix from its backup'
    'report:render a report/export from saved findings'
    'providers:list AI providers'
    'setup:first-run wizard to pick an offline AI model (--update re-pulls local models)'
    'update-oval:download the OpenSCAP OVAL feed'
    'scheduled:non-interactive scan + dated report'
    'dashboard:serve saved findings over an HTTPS login dashboard'
    'audit:show the remediation audit log (applied fixes & rollbacks)'
    'news:show recent vulnerability advisories (CISA KEV, NVD, errata)'
    'network:manage the network scanner'\''s authorized-target allow-list'
  )
  sev=(low moderate important critical)
  scanners=(dnf oscap ssh systemd ports webroot container effective fips network)
  providers=(claude openai gemini kimi deepseek mistral local)

  _arguments -C \
    '(-h --help)'{-h,--help}'[show help]' \
    '--version[show version and exit]' \
    '--no-banner[suppress the startup banner]' \
    '--config[config JSON path]:file:_files' \
    '--state-dir[state/cache directory]:dir:_files -/' \
    "--provider[AI provider]:provider:($providers)" \
    '--model[model id override]:model:' \
    '1: :->cmd' \
    '*:: :->args' && return

  case $state in
    cmd)
      _describe -t commands 'vulnscan-ai command' cmds ;;
    args)
      case $line[1] in
        scan)
          _arguments \
            "*--scanner[scanner to run]:scanner:($scanners)" \
            '--all[run every available scanner]' \
            "--min-severity[severity floor]:severity:($sev)" \
            '--no-enrich[skip CVE-feed enrichment]' \
            '--pdf[write PDF report]:file:_files' \
            '--json[write JSON export]:file:_files' \
            '--sarif[write SARIF 2.1.0]:file:_files' \
            '*--ignore[suppress matching findings]:pattern:' \
            '--compliance[run a compliance benchmark instead of a vuln scan]:profile:(cis-l1 cis-l2 cis-ws-l1 cis-ws-l2 stig stig-gui pci-dss hipaa ospp cui anssi-minimal anssi-intermediary anssi-enhanced anssi-high e8)' \
            '--list-profiles[list compliance profiles this host offers]' \
            '--compliance-datastream[override the SCAP datastream]:file:_files' ;;
        fix)
          _arguments \
            '--scan[scan first]' \
            "*--scanner[scanner to run]:scanner:($scanners)" \
            '--all[with --scan: run every available scanner]' \
            '--no-enrich[skip CVE-feed enrichment]' \
            "--min-severity[severity floor]:severity:($sev)" \
            '--yes[auto-approve every fix]' \
            '--dry-run[plan only; execute nothing]' \
            '--pdf[write PDF report]:file:_files' \
            '--export-script[write a bash fix script]:file:_files' \
            '--export-ansible[write an Ansible playbook]:file:_files' \
            '*--ignore[suppress matching findings]:pattern:' \
            '(--no-catalog)--offline[plan from the offline catalog only; never call a provider]' \
            '(--offline)--no-catalog[disable the offline catalog; use the AI provider for every finding]' \
            '--no-scap-grounding[disable grounding AI prompts with matching SSG hardening snippets]' ;;
        rollback)
          _arguments \
            '--list[list fixes with a stored backup]' \
            '1:finding id:' ;;
        report)
          _arguments \
            '(-o --output)'{-o,--output}'[output path (.pdf/.html/.json/.sarif)]:file:_files' \
            "--min-severity[severity floor]:severity:($sev)" ;;
        scheduled)
          _arguments \
            "*--scanner[scanner to run]:scanner:($scanners)" \
            '--all[run every available scanner]' \
            '--no-enrich[skip CVE-feed enrichment]' \
            "--min-severity[severity floor]:severity:($sev)" \
            '--plan[embed AI proposals (no execution)]' \
            '--html[HTML report instead of PDF]' \
            '--keep[retain N reports]:n:' \
            "--fail-on[exit 3 at/above severity]:severity:($sev)" ;;
        dashboard)
          _arguments \
            '--set-password[set the admin password, then exit]' \
            '--user[admin username]:user:' \
            '*--allow[permit a network client]:ip/cidr:' \
            '*--deny[remove a permitted client]:ip/cidr:' \
            '--list[show dashboard settings, then exit]' \
            '--enable-fix[allow applying fixes from the dashboard UI, then exit]' \
            '--disable-fix[disable applying fixes from the dashboard UI, then exit]' \
            '--port[listen port]:port:' \
            '--bind[bind address]:address:' ;;
        audit)
          _arguments \
            '--limit[how many recent events to show (0=all)]:n:' \
            '--json[emit the raw events as JSON]' ;;
        news)
          _arguments \
            '--source[only one feed source]:source:(kev nvd distro)' \
            '--refresh[fetch fresh data instead of the cache]' \
            '--limit[max advisories to show]:n:' ;;
        network)
          _arguments \
            '*--add[authorize a target]:host/cidr:' \
            '*--remove[remove a target]:host/cidr:' \
            '--list[show configured targets and settings, then exit]' \
            '--ports[port-scan breadth]:spec:(known top1000 all)' ;;
        setup)
          _arguments \
            '--update[re-pull the downloaded Ollama models instead of running the wizard]' ;;
        *) _message 'no more arguments' ;;
      esac ;;
  esac
}

_vulnscan-ai "$@"
