#!/bin/bash

REPO_URL=""
MIRROR_DIR=""
INDEX_URL=""
SKIP_EXISTING=true

function show_help() {
    echo "Usage: $(basename "$0") [options]"
    echo ""
    echo "Options:"
    echo "  -r, --repo-url URL         Helm chart repository URL (required)"
    echo "  -d, --mirror-dir DIR       Directory to store mirrored repository (default: hostname from REPO_URL)"
    echo "  -u, --index-url URL        URL to be used in index.yaml (--url option of \`helm repo index\`)"
    echo "  -ns, --no-skip-existing    Don't skip downloading existing files"
}

while [[ $# -gt 0 ]]; do
    key="$1"
    case $key in
    -r | --repo-url)
        REPO_URL="$2"
        shift 2
        ;;
    -d | --mirror-dir)
        MIRROR_DIR="$2"
        shift 2
        ;;
    -u | --index-url)
        INDEX_URL="$2"
        shift 2
        ;;
    -ns | --no-skip-existing)
        SKIP_EXISTING=false
        shift 2
        ;;
    -h | --help)
        show_help
        exit 0
        ;;
    *)
        echo "Unknown option: $1"
        echo ""
        show_help
        exit 1
        ;;
    esac
done

if [[ -z "$REPO_URL" ]]; then
    echo "Error: --repo-url is required."
    show_help
    exit 1
fi

if [[ -z "$MIRROR_DIR" ]]; then
    MIRROR_DIR="./$(echo "$REPO_URL" | sed -E 's;https?://([^/]+)/?.*;\1;')-mirror"
fi

echo "Using MIRROR_DIR: $MIRROR_DIR"
mkdir -p "$MIRROR_DIR"
cd "$MIRROR_DIR" || exit

echo "Downloading index.yaml from $REPO_URL"
wget -q "$REPO_URL/index.yaml" -O "index.yaml"
if [[ $? -ne 0 ]]; then
    echo "Error: Failed to download index.yaml from $REPO_URL"
    exit 1
fi

echo "Extracting chart download URLs from index.yaml"
chart_urls=$(yq eval '.entries | .[] | .[] | .urls[]' index.yaml)
if [[ -z "$chart_urls" ]]; then
    echo "Error: No chart URLs found in index.yaml"
    exit 1
fi

IFS=$'\n' read -r -d '' -a chart_urls_array < <(printf '%s\0' "$chart_urls")
declare -a file_urls=()
declare -a oci_urls=()
for url in "${chart_urls_array[@]}"; do
    if [[ "$url" != http://* && "$url" != https://* && "$url" != oci://* ]]; then
        url="${REPO_URL%/}/$url"
    fi
    if [[ $url == oci://* ]]; then
        oci_urls+=("$url")
    else
        file_urls+=("$url")
    fi
done
echo "Total: ${#file_urls[@]} charts in files and ${#oci_urls[@]} charts in OCI registries"

WGET_OPTIONS="-q"
if [[ "$SKIP_EXISTING" == true ]]; then
    WGET_OPTIONS+=" --no-clobber"
fi

if [[ ${#file_urls[@]} -gt 0 ]]; then
    echo "Downloading ${#file_urls[@]} chart packages in parallel"
    printf '%s\n' "${file_urls[@]}" | xargs -n 1 -P 8 wget $WGET_OPTIONS
    if [[ $? -ne 0 ]]; then
        echo "Error: Failed to download some chart packages"
        exit 1
    fi
fi

if [[ ${#oci_urls[@]} -gt 0 ]]; then
    echo "Pulling ${#oci_urls[@]} OCI charts"
    for oci_url in "${oci_urls[@]}"; do
        tag=$(echo "$oci_url" | rev | cut -d':' -f1 | rev)
        oci_url=$(echo "$oci_url" | rev | cut -d':' -f2- | rev)
        helm pull "$oci_url" --version "$tag"
        if [[ $? -ne 0 ]]; then
            echo "Error: Failed to pull OCI chart $oci_url"
            exit 1
        fi
    done
fi

echo "Generating new index.yaml for the local repository"
if [[ -n "$INDEX_URL" ]]; then
    helm repo index . --url "$INDEX_URL"
else
    helm repo index .
fi
if [[ $? -ne 0 ]]; then
    echo "Error: Failed to generate index.yaml"
    exit 1
fi

echo "Helm repository mirror has been created in $MIRROR_DIR"
