#!/usr/bin/env bash

set -e

PROGNAME="${BASH_SOURCE[0]}"
HERE="$(cd "$(dirname "$PROGNAME")" &>/dev/null && pwd)"
ROOT=$(cd "$HERE/.." && pwd)
GET_PLATFORM="$ROOT/sbin/get-platform"

eprint() { >&2 echo "$@"; }


print_help() {
    cat <<-END
Usage: upload-artifacts [OPTIONS] [artifacts...]

Uploads packages to S3.

Options:
  --help, help        Show this help message and exit
  --nop, -n           No operation (dry-run)
  --verbose, -v       Show artifact details
  --force, -f         Force upload even if not in CI

Environment variables can also be set:
  NOP=1               No operation (dry-run)
  VERBOSE=1           Show artifact details
  FORCE=1             Force upload even if not in CI
  HELP=1              Show help
END
}

#----------------------------------------------------------------------------------------------

# Parse command line arguments
parse_args() {
    while [[ $# -gt 0 ]]; do
        case "$1" in
            --help|help)
                print_help
                exit 0
                ;;
            --nop|-n)
                NOP=1
                ;;
            --verbose|-v)
                VERBOSE=1
                ;;
            --force|-f)
                FORCE=1
                ;;
            *)
                # Store remaining arguments for later processing
                ARTIFACTS+=("$1")
                ;;
        esac
        shift
    done
}

# Initialize variables
ARTIFACTS=()

# Check for help flag in environment variable
if [[ $HELP == 1 ]]; then
    print_help
    exit 0
fi

# Parse command line arguments
parse_args "$@"

# If no specific artifacts provided, we'll use defaults later

ARCH=$($GET_PLATFORM --arch)

OS=$($GET_PLATFORM --os)
[[ $OS == linux ]] && OS=Linux

OSNICK=$($GET_PLATFORM --version-artifact)

PLATFORM="$OS-$OSNICK-$ARCH"
echo "Detected OS: $OS"
echo "Detected OSNICK: $OSNICK"
echo "Detected ARCH: $ARCH"
echo "Detected PLATFORM: $PLATFORM"

OP=""
[[ $NOP == 1 ]] && OP=echo
S3_URL=s3://redismodules


if [[ -z $GITHUB_ACTIONS && $FORCE != 1 ]]; then
    eprint "Cannot upload outside of GitHub Actions. Override with FORCE=1."
    exit 1
fi

if [[ -z $AWS_ACCESS_KEY_ID || -z $AWS_SECRET_ACCESS_KEY ]]; then
	eprint "No credentials for S3 upload."
	exit 1
fi


#----------------------------------------------------------------------------------------------
# Navigate to artifacts directory
cd "$ROOT/bin/artifacts/snapshots"

if [[ $VERBOSE == 1 ]]; then
    if [[ $OSNICK == alpine3 ]]; then
        du -ah *
    else
        du -ah --apparent-size *
    fi
fi

#----------------------------------------------------------------------------------------------
# S3 Upload Functions

s3_upload_file() {
    local file="$1"
    local s3_dir="$2"
    [[ $s3_dir != */ ]] && s3_dir="${s3_dir}/"

    $OP aws s3 cp "$file" "$s3_dir" --acl public-read --no-progress

    # Verify the file was uploaded
    local file_name=$(basename "$file")
    if ! $OP aws s3 ls "${s3_dir}${file_name}" > /dev/null 2>&1; then
        eprint "Failed to verify that $file_name was uploaded to $s3_dir"
        return 1
    fi
}

s3_upload() {
    # Parameters:
    #   $1: product_name - Product folder name in S3 (e.g., "redisearch")
    #   $2: file_prefix - Prefix of files to upload (e.g., "redisearch")
    local product_name="$1"
    local file_prefix="$2"

    if [[ -z "$file_prefix" || -z "$product_name" ]]; then
        eprint "Error: Missing required parameters"
        eprint "Usage: s3_upload <product_name> <file_prefix>"
        return 1
    fi


    local files file

    # print the current folder name
    shopt -s nullglob
    files=("${file_prefix}."*"${PLATFORM}"*.zip)
    shopt -u nullglob
    echo "Found files: ${files[@]}"
    if [[ ${#files[@]} -eq 0 ]]; then
        echo "      Warning: No files found matching pattern: ${file_prefix}.*${PLATFORM}*.zip"
        return 0
    fi

    # Always upload to snapshots with original filename
    local subdir="snapshots"
    local upload_dir="${S3_URL}/${product_name}/${subdir}"
    echo "Uploading to snapshots directory: $upload_dir"
    VERSION_SUFFIX="${VERSION_SUFFIX:-}"
    for file in "${files[@]}"; do
        local temp_file="${file%.zip}${VERSION_SUFFIX}.zip"
        cp "$file" "$temp_file"
        s3_upload_file "$temp_file" "$upload_dir"
        rm -f "$temp_file"
    done
    echo "Snapshots upload complete to $upload_dir"

    # For beta versions, also upload to beta directory with BETA_VERSION suffix
    if [[ -n "$BETA_VERSION" ]]; then
        echo "Beta version detected: $BETA_VERSION"
        subdir="beta"
        upload_dir="${S3_URL}/${product_name}/${subdir}"
        echo "Also uploading to beta directory: $upload_dir"

        for file in "${files[@]}"; do
            local base_name=$(basename "$file")
            # Replace .master. or .main. from beta version filename and add BETA_VERSION
            local new_name="${base_name/.master./.${BETA_VERSION}.}"
            new_name="${new_name/.main./.${BETA_VERSION}.}"
            # Create temp file with new name
            local temp_file="./${new_name%.zip}${VERSION_SUFFIX}.zip"
            cp "$file" "$temp_file"
            s3_upload_file "$temp_file" "$upload_dir"
            rm -f "$temp_file"
        done
        echo "Beta upload complete to $upload_dir"
    fi
}
upload_product() {
    local target="$1"
    local prefix="$2"

    {
        echo "::group::Uploading $prefix artifacts"
        s3_upload "$target" "$prefix"
        echo "::endgroup::"
    } || {
        echo "::endgroup::"
        eprint "Error occurred while uploading $prefix artifacts"
        exit 1
    }
}

# Main upload process
upload_product "redisearch-oss" "redisearch-community"
upload_product "redisearch" "redisearch"
