#!/usr/bin/env bash
set -euo pipefail

TARGET_ROOT="${1:-.}"
BLACKSHIELD_SITE_URL="${BLACKSHIELD_SITE_URL:-https://app.blackshield.chaplau.com}"
BLACKSHIELD_API_URL="${BLACKSHIELD_API_URL:-$BLACKSHIELD_SITE_URL}"

mkdir -p "$TARGET_ROOT/deploy/helm/blackshield-k8s-scanner"
cat > "$TARGET_ROOT/deploy/helm/blackshield-k8s-scanner/Chart.yaml" <<EOF
apiVersion: v2
name: blackshield-k8s-scanner
description: >
  BlackShield Kubernetes scanner. Runs kube-bench (CIS benchmarks),
  kubescape, and Kyverno policy telemetry on a schedule and ingests
  findings into the Security Platform.
type: application
version: 1.0.0
appVersion: "1.0.0"
keywords:
  - security
  - kubernetes
  - compliance
  - cis
  - kubescape
  - kube-bench
home: ${BLACKSHIELD_SITE_URL}
maintainers:
  - name: BlackShield Team
    email: support@blackshield.chaplau.com
EOF

mkdir -p "$TARGET_ROOT/deploy/helm/blackshield-k8s-scanner/templates"
cat > "$TARGET_ROOT/deploy/helm/blackshield-k8s-scanner/templates/_helpers.tpl" <<'EOF'
{{/*
Expand the name of the chart.
*/}}
{{- define "blackshield-k8s-scanner.name" -}}
{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" }}
{{- end }}

{{/*
Create a default fully qualified app name.
*/}}
{{- define "blackshield-k8s-scanner.fullname" -}}
{{- if .Values.fullnameOverride }}
{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" }}
{{- else }}
{{- $name := default .Chart.Name .Values.nameOverride }}
{{- if contains $name .Release.Name }}
{{- .Release.Name | trunc 63 | trimSuffix "-" }}
{{- else }}
{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" }}
{{- end }}
{{- end }}
{{- end }}

{{/*
Common labels
*/}}
{{- define "blackshield-k8s-scanner.labels" -}}
helm.sh/chart: {{ include "blackshield-k8s-scanner.name" . }}-{{ .Chart.Version | replace "+" "_" }}
{{ include "blackshield-k8s-scanner.selectorLabels" . }}
app.kubernetes.io/version: {{ .Chart.AppVersion | quote }}
app.kubernetes.io/managed-by: {{ .Release.Service }}
app.kubernetes.io/component: k8s-scanner
app.kubernetes.io/part-of: blackshield
{{- end }}

{{/*
Selector labels
*/}}
{{- define "blackshield-k8s-scanner.selectorLabels" -}}
app.kubernetes.io/name: {{ include "blackshield-k8s-scanner.name" . }}
app.kubernetes.io/instance: {{ .Release.Name }}
{{- end }}
EOF

mkdir -p "$TARGET_ROOT/deploy/helm/blackshield-k8s-scanner/templates"
cat > "$TARGET_ROOT/deploy/helm/blackshield-k8s-scanner/templates/clusterrole.yaml" <<'EOF'
{{- if .Values.rbac.create -}}
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  name: {{ include "blackshield-k8s-scanner.fullname" . }}
  labels:
    {{- include "blackshield-k8s-scanner.labels" . | nindent 4 }}
rules:
  {{- toYaml .Values.rbac.clusterRoleRules | nindent 2 }}
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  name: {{ include "blackshield-k8s-scanner.fullname" . }}
  labels:
    {{- include "blackshield-k8s-scanner.labels" . | nindent 4 }}
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: {{ include "blackshield-k8s-scanner.fullname" . }}
subjects:
  - kind: ServiceAccount
    name: {{ .Values.serviceAccount.name | default (include "blackshield-k8s-scanner.fullname" .) }}
    namespace: {{ .Release.Namespace }}
{{- end }}
EOF

mkdir -p "$TARGET_ROOT/deploy/helm/blackshield-k8s-scanner/templates"
cat > "$TARGET_ROOT/deploy/helm/blackshield-k8s-scanner/templates/cronjob.yaml" <<'EOF'
{{- if eq .Values.mode "cronjob" -}}
apiVersion: batch/v1
kind: CronJob
metadata:
  name: {{ include "blackshield-k8s-scanner.fullname" . }}
  namespace: {{ .Release.Namespace }}
  labels:
    {{- include "blackshield-k8s-scanner.labels" . | nindent 4 }}
spec:
  schedule: {{ .Values.cronSchedule | quote }}
  concurrencyPolicy: Forbid
  successfulJobsHistoryLimit: 3
  failedJobsHistoryLimit: 3
  jobTemplate:
    spec:
      template:
        metadata:
          labels:
            {{- include "blackshield-k8s-scanner.selectorLabels" . | nindent 12 }}
        spec:
          serviceAccountName: {{ .Values.serviceAccount.name | default (include "blackshield-k8s-scanner.fullname" .) }}
          restartPolicy: OnFailure
          securityContext:
            {{- toYaml .Values.podSecurityContext | nindent 12 }}
          containers:
            - name: scanner
              image: "{{ .Values.image.repository }}:{{ .Values.image.tag | default .Chart.AppVersion }}"
              imagePullPolicy: {{ .Values.image.pullPolicy }}
              securityContext:
                {{- toYaml .Values.securityContext | nindent 16 }}
              env:
                {{- range $key, $val := .Values.env }}
                - name: {{ $key }}
                  value: {{ $val | quote }}
                {{- end }}
                - name: SCAN_INTERVAL_SECONDS
                  value: "0"
                {{- if .Values.existingSecret.name }}
                - name: BLACKSHIELD_API_KEY
                  valueFrom:
                    secretKeyRef:
                      name: {{ .Values.existingSecret.name }}
                      key: {{ .Values.existingSecret.key }}
                {{- end }}
              resources:
                {{- toYaml .Values.resources | nindent 16 }}
              {{- with .Values.extraVolumeMounts }}
              volumeMounts:
                {{- toYaml . | nindent 16 }}
              {{- end }}
          {{- with .Values.extraVolumes }}
          volumes:
            {{- toYaml . | nindent 12 }}
          {{- end }}
{{- end }}
EOF

mkdir -p "$TARGET_ROOT/deploy/helm/blackshield-k8s-scanner/templates"
cat > "$TARGET_ROOT/deploy/helm/blackshield-k8s-scanner/templates/deployment.yaml" <<'EOF'
{{- if eq .Values.mode "deployment" -}}
apiVersion: apps/v1
kind: Deployment
metadata:
  name: {{ include "blackshield-k8s-scanner.fullname" . }}
  namespace: {{ .Release.Namespace }}
  labels:
    {{- include "blackshield-k8s-scanner.labels" . | nindent 4 }}
spec:
  replicas: 1
  selector:
    matchLabels:
      {{- include "blackshield-k8s-scanner.selectorLabels" . | nindent 6 }}
  template:
    metadata:
      labels:
        {{- include "blackshield-k8s-scanner.selectorLabels" . | nindent 8 }}
    spec:
      serviceAccountName: {{ .Values.serviceAccount.name | default (include "blackshield-k8s-scanner.fullname" .) }}
      securityContext:
        {{- toYaml .Values.podSecurityContext | nindent 8 }}
      containers:
        - name: scanner
          image: "{{ .Values.image.repository }}:{{ .Values.image.tag | default .Chart.AppVersion }}"
          imagePullPolicy: {{ .Values.image.pullPolicy }}
          securityContext:
            {{- toYaml .Values.securityContext | nindent 12 }}
          ports:
            - name: health
              containerPort: 8080
              protocol: TCP
          env:
            {{- range $key, $val := .Values.env }}
            - name: {{ $key }}
              value: {{ $val | quote }}
            {{- end }}
            - name: SCAN_INTERVAL_SECONDS
              value: {{ .Values.scanIntervalSeconds | quote }}
            {{- if .Values.existingSecret.name }}
            - name: BLACKSHIELD_API_KEY
              valueFrom:
                secretKeyRef:
                  name: {{ .Values.existingSecret.name }}
                  key: {{ .Values.existingSecret.key }}
            {{- end }}
          livenessProbe:
            {{- toYaml .Values.livenessProbe | nindent 12 }}
          readinessProbe:
            {{- toYaml .Values.readinessProbe | nindent 12 }}
          resources:
            {{- toYaml .Values.resources | nindent 12 }}
          {{- with .Values.extraVolumeMounts }}
          volumeMounts:
            {{- toYaml . | nindent 12 }}
          {{- end }}
      {{- with .Values.extraVolumes }}
      volumes:
        {{- toYaml . | nindent 8 }}
      {{- end }}
      {{- with .Values.nodeSelector }}
      nodeSelector:
        {{- toYaml . | nindent 8 }}
      {{- end }}
      {{- with .Values.affinity }}
      affinity:
        {{- toYaml . | nindent 8 }}
      {{- end }}
      {{- with .Values.tolerations }}
      tolerations:
        {{- toYaml . | nindent 8 }}
      {{- end }}
{{- end }}
EOF

mkdir -p "$TARGET_ROOT/deploy/helm/blackshield-k8s-scanner/templates"
cat > "$TARGET_ROOT/deploy/helm/blackshield-k8s-scanner/templates/networkpolicy.yaml" <<'EOF'
{{- if .Values.networkPolicy.enabled -}}
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: {{ include "blackshield-k8s-scanner.fullname" . }}
  namespace: {{ .Release.Namespace }}
  labels:
    {{- include "blackshield-k8s-scanner.labels" . | nindent 4 }}
spec:
  podSelector:
    matchLabels:
      {{- include "blackshield-k8s-scanner.selectorLabels" . | nindent 6 }}
  policyTypes:
    - Egress
  egress:
    {{- toYaml .Values.networkPolicy.egressRules | nindent 4 }}
{{- end }}
EOF

mkdir -p "$TARGET_ROOT/deploy/helm/blackshield-k8s-scanner/templates"
cat > "$TARGET_ROOT/deploy/helm/blackshield-k8s-scanner/templates/serviceaccount.yaml" <<'EOF'
{{- if .Values.serviceAccount.create -}}
apiVersion: v1
kind: ServiceAccount
metadata:
  name: {{ .Values.serviceAccount.name | default (include "blackshield-k8s-scanner.fullname" .) }}
  namespace: {{ .Release.Namespace }}
  labels:
    {{- include "blackshield-k8s-scanner.labels" . | nindent 4 }}
  {{- with .Values.serviceAccount.annotations }}
  annotations:
    {{- toYaml . | nindent 4 }}
  {{- end }}
{{- end }}
EOF

mkdir -p "$TARGET_ROOT/deploy/helm/blackshield-k8s-scanner"
cat > "$TARGET_ROOT/deploy/helm/blackshield-k8s-scanner/values.yaml" <<EOF
# ── Image ─────────────────────────────────────────────────────────────────────
image:
  repository: public.ecr.aws/blackshield-security/k8s-scanner
  tag: "1.0.0"
  pullPolicy: IfNotPresent

# ── Deployment mode ───────────────────────────────────────────────────────────
# "deployment" → long-running pod, internal loop controlled by scanIntervalSeconds
# "cronjob"    → Kubernetes CronJob, run with SCAN_INTERVAL_SECONDS=0
mode: deployment

scanIntervalSeconds: 21600    # 6 h; ignored when mode=cronjob
cronSchedule: "0 */6 * * *"  # used when mode=cronjob

# ── Platform settings ─────────────────────────────────────────────────────────
env:
  BLACKSHIELD_API_URL: "${BLACKSHIELD_API_URL}"
  LOG_LEVEL: INFO
  BATCH_SIZE: "500"

# Provide one of:
#   (a) env.BLACKSHIELD_API_KEY  — inline (non-prod only)
#   (b) existingSecret           — reference an existing Secret (recommended)
existingSecret:
  name: ""    # e.g. blackshield-k8s-scanner
  key: ""     # e.g. api-key

# ── RBAC ──────────────────────────────────────────────────────────────────────
rbac:
  create: true
  clusterRoleRules:
    - apiGroups: [""]
      resources:
        - nodes
        - pods
        - namespaces
        - serviceaccounts
        - configmaps
        - secrets
        - services
        - endpoints
        - persistentvolumes
        - persistentvolumeclaims
        - resourcequotas
        - limitranges
      verbs: ["get", "list", "watch"]
    - apiGroups: ["apps"]
      resources:
        - deployments
        - daemonsets
        - statefulsets
        - replicasets
      verbs: ["get", "list", "watch"]
    - apiGroups: ["batch"]
      resources: ["jobs", "cronjobs"]
      verbs: ["get", "list", "watch"]
    - apiGroups: ["rbac.authorization.k8s.io"]
      resources:
        - clusterroles
        - clusterrolebindings
        - roles
        - rolebindings
      verbs: ["get", "list", "watch"]
    - apiGroups: ["networking.k8s.io"]
      resources: ["networkpolicies", "ingresses"]
      verbs: ["get", "list", "watch"]
    - apiGroups: ["policy"]
      resources: ["podsecuritypolicies"]
      verbs: ["get", "list", "watch"]
    - apiGroups: ["kyverno.io"]
      resources: ["clusterpolicies", "policies"]
      verbs: ["get", "list", "watch"]
    - apiGroups: ["admissionregistration.k8s.io"]
      resources:
        - mutatingwebhookconfigurations
        - validatingwebhookconfigurations
      verbs: ["get", "list", "watch"]

# ── Service account ───────────────────────────────────────────────────────────
serviceAccount:
  create: true
  name: blackshield-k8s-scanner
  annotations: {}

# ── Pod security ──────────────────────────────────────────────────────────────
podSecurityContext:
  runAsNonRoot: true
  runAsUser: 1000
  runAsGroup: 1000
  fsGroup: 1000
  seccompProfile:
    type: RuntimeDefault

securityContext:
  allowPrivilegeEscalation: false
  readOnlyRootFilesystem: true
  capabilities:
    drop: ["ALL"]

# ── Health probes ─────────────────────────────────────────────────────────────
livenessProbe:
  httpGet:
    path: /health
    port: 8080
  initialDelaySeconds: 30
  periodSeconds: 30
  failureThreshold: 3

readinessProbe:
  httpGet:
    path: /health
    port: 8080
  initialDelaySeconds: 10
  periodSeconds: 10

# ── Network policy ────────────────────────────────────────────────────────────
networkPolicy:
  enabled: true
  # Allow egress to the platform API (port 443) only.
  # Restrict further by adding ipBlock rules.
  egressRules:
    - ports:
        - port: 443
          protocol: TCP
    - ports:
        - port: 53
          protocol: UDP

# ── Resources ─────────────────────────────────────────────────────────────────
resources:
  requests:
    cpu: 200m
    memory: 256Mi
  limits:
    cpu: "1"
    memory: 1Gi

# ── Tolerations / node selector ───────────────────────────────────────────────
tolerations: []
nodeSelector: {}
affinity: {}

# ── Extra volume mounts (e.g. host paths for kube-bench) ─────────────────────
extraVolumes: []
extraVolumeMounts: []
EOF

printf "Wrote source bundle files:
"
printf "  - %s\n" "$TARGET_ROOT/deploy/helm/blackshield-k8s-scanner/Chart.yaml"
printf "  - %s\n" "$TARGET_ROOT/deploy/helm/blackshield-k8s-scanner/templates/_helpers.tpl"
printf "  - %s\n" "$TARGET_ROOT/deploy/helm/blackshield-k8s-scanner/templates/clusterrole.yaml"
printf "  - %s\n" "$TARGET_ROOT/deploy/helm/blackshield-k8s-scanner/templates/cronjob.yaml"
printf "  - %s\n" "$TARGET_ROOT/deploy/helm/blackshield-k8s-scanner/templates/deployment.yaml"
printf "  - %s\n" "$TARGET_ROOT/deploy/helm/blackshield-k8s-scanner/templates/networkpolicy.yaml"
printf "  - %s\n" "$TARGET_ROOT/deploy/helm/blackshield-k8s-scanner/templates/serviceaccount.yaml"
printf "  - %s\n" "$TARGET_ROOT/deploy/helm/blackshield-k8s-scanner/values.yaml"
