#!/bin/bash

fetch_secret() {
    local sealed_secret_path=$1

    # Prompt if no path provided
    while [[ -z "$sealed_secret_path" ]]; do
        echo -n "📄 Enter path to the SealedSecret YAML file: "
        read sealed_secret_path
    done

    # Ensure file exists
    if [[ ! -f "$sealed_secret_path" ]]; then
        echo "❌ File not found: $sealed_secret_path"
        exit 1
    fi

    if ! cat "$sealed_secret_path" | kubeseal --validate; then
        echo "❌ SealedSecret validation failed for: $sealed_secret_path"
        exit 1
    fi

    # Check if the kind of the file is SealedSecret
    local kind=$(yq eval '.kind' "$sealed_secret_path")
    if [[ "$kind" != "SealedSecret" ]]; then
        echo "❌ The file is not a SealedSecret."
        exit 1
    fi

    # Derive the secret_output_path by removing 'sealed-' from the sealed_secret_path
    local secret_output_path="${sealed_secret_path/sealed-/}"

    # Extract name and namespace from spec.template.metadata
    local secret_name=$(yq eval '.spec.template.metadata.name // ""' "$sealed_secret_path")
    local secret_namespace=$(yq eval '.spec.template.metadata.namespace // ""' "$sealed_secret_path")

    if [[ -z "$secret_name" || -z "$secret_namespace" ]]; then
        echo "❌ Missing name or namespace in spec.template.metadata."
        exit 1
    fi

    if ! kubectl version >/dev/null 2>&1; then
    echo "❌ Cannot connect to Kubernetes cluster. Check your context or credentials."
    exit 1
    fi

    echo "📡 Fetching secret: $secret_name from namespace: $secret_namespace"

    # Fetch the secret from Kubernetes
    raw_secret=$(kubectl get secret "$secret_name" -n "$secret_namespace" -o yaml 2>/dev/null)

    if [[ -z "$raw_secret" ]]; then
        echo "❌ Failed to fetch the secret from Kubernetes."
        exit 1
    fi

    # Extract the encryptedData keys into a list of strings
    encrypted_data_keys=$(yq eval -o=json '.spec.encryptedData | keys' "$sealed_secret_path" | jq -c '.')

    # Extract metadata from the sealed secret and convert it to JSON
    metadata_json=$(yq eval '.spec.template.metadata' "$sealed_secret_path" | yq eval -o=json)

    # Construct new Secret YAML
    echo "$raw_secret" | yq eval "
        .apiVersion = \"v1\" |
        .kind = \"Secret\" |
        .metadata = $metadata_json |
        del(.metadata.creationTimestamp) |
        .stringData = (.data | with_entries(select(.key as \$k | ($encrypted_data_keys | map(select(. == \$k))) | length > 0) | .value |= @base64d)) |
        del(.data)
    " - > "$secret_output_path"

    if [[ $? -ne 0 ]]; then
        echo "❌ Failed to process the secret."
        exit 1
    fi

    echo "✅ Secret has been written to: $secret_output_path"
}

# Accept path as optional argument
sealed_secret_path="$1"
fetch_secret "$sealed_secret_path"