#!/usr/bin/env bash

# Copyright (c) 2026 Tigera, Inc. All rights reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

# Collect diagnostics from a kind-based e2e cluster and upload them as a job
# artifact for inspection. Drives `calico ctl cluster diags`, which packages
# logs, descriptions, TLS state, and Calico resources into a single tarball.
#
# Intended to be called from the e2e job epilogue. Best-effort: missing
# kubeconfig, missing image, or a torn-down cluster is not an error.

set -x

my_dir="$(dirname "$0")"
repo_dir="$(cd "$my_dir/.." && pwd)"
artifacts_dir="$repo_dir/artifacts"

kubeconfig="${KUBECONFIG:-$repo_dir/hack/test/kind/kind-kubeconfig.yaml}"
if [ ! -f "$kubeconfig" ]; then
  echo "collect-kind-diags: no kubeconfig at $kubeconfig, skipping"
  exit 0
fi

# Use the kubectl that the kind setup downloaded; the diags binary shells out
# to `kubectl` for some collection steps.
kubectl_bin="$repo_dir/hack/test/kind/kubectl"
if [ ! -x "$kubectl_bin" ]; then
  kubectl_bin="$(command -v kubectl || true)"
fi
if [ -z "$kubectl_bin" ]; then
  echo "collect-kind-diags: kubectl not found, skipping"
  exit 0
fi

if ! "$kubectl_bin" --kubeconfig="$kubeconfig" cluster-info >/dev/null 2>&1; then
  echo "collect-kind-diags: cluster unreachable, skipping"
  exit 0
fi

# Extract the calico binary from the locally-built image to run cluster diags.
# The combined `calico` binary dispatches `ctl` to the calicoctl subcommand.
#
# Use the daemon-local calico/calico:latest-<arch> tag, which is present in both
# paths: load-cached-images `docker load`s it on a cache hit, and the build
# produces it on a miss. The localhost:5000/...:test-build tag the cluster pulls
# from is only ever `docker tag`d from latest-<arch> for the push, so it isn't
# reliably left in the daemon - extracting from it was silently skipping diags.
arch="${ARCH:-amd64}"
calico_image="${CALICO_IMAGE:-calico/calico:latest-${arch}}"
calico_bin="$(mktemp -d)/calico"
cid="$(docker create "$calico_image" 2>/dev/null)"
if [ -z "$cid" ]; then
  echo "collect-kind-diags: no local $calico_image to extract a binary from, skipping"
  exit 0
fi
if ! docker cp "$cid:/usr/bin/calico" "$calico_bin"; then
  docker rm -f "$cid" >/dev/null 2>&1 || true
  echo "collect-kind-diags: could not extract calico binary, skipping"
  exit 0
fi
docker rm -f "$cid" >/dev/null 2>&1 || true
chmod +x "$calico_bin"

mkdir -p "$artifacts_dir"

# `calico ctl cluster diags` writes a calico-diagnostics-<timestamp>.tar.gz
# into the working directory, so run it from artifacts/. The default --config
# points at /etc/calico/calicoctl.cfg, which doesn't exist on the CI host —
# calicoctl tolerates that and falls back to DATASTORE_TYPE / KUBECONFIG. Up
# max-logs from the default 5 so we don't miss restarted pods on busier kind
# runs.
cd "$artifacts_dir"
PATH="$(dirname "$kubectl_bin"):$PATH" \
DATASTORE_TYPE=kubernetes \
KUBECONFIG="$kubeconfig" \
  "$calico_bin" ctl cluster diags \
    --max-logs=100 \
    --allow-version-mismatch \
  || echo "collect-kind-diags: cluster diags exited non-zero (continuing)"

# Upload the bundle here rather than leaving it for .semaphore/publish-artifacts.
# publish-artifacts runs in the global job epilogue, which executes *before* this
# on_fail step, so by the time it runs the bundle doesn't exist yet and is never
# uploaded. Pushing it directly makes the diags actually retrievable.
if command -v artifact >/dev/null 2>&1; then
  for bundle in calico-diagnostics-*.tar.gz; do
    [ -e "$bundle" ] || continue
    artifact push job "$bundle" -d "diags/$bundle" \
      || echo "collect-kind-diags: failed to push $bundle (continuing)"
  done
else
  echo "collect-kind-diags: 'artifact' CLI not found; bundle left in $artifacts_dir"
fi

exit 0
