#!/usr/bin/env bash

#############################################################################
# GitHub Artifact Downloader
#
# Download and extract GitHub Actions artifacts with style
#
# Usage:
#   artifact_github_download.sh <REPO> [OPTIONS]
#
# Arguments:
#   REPO                GitHub repository (owner/repo)
#
# Options:
#   -n, --name NAME     Artifact name to download (preselect)
#   -o, --output DIR    Output directory (default: current directory)
#   -h, --help          Show this help message
#
# Examples:
#   artifact_github_download.sh valknarness/awesome
#   artifact_github_download.sh valknarness/awesome -n awesome-database-latest
#   artifact_github_download.sh valknarness/awesome -o ~/downloads
#############################################################################

set -euo pipefail

# ============================================================================
# Color Definitions
# ============================================================================

# Check if terminal supports colors
if [[ -t 1 ]] && command -v tput >/dev/null 2>&1; then
    COLORS=$(tput colors 2>/dev/null || echo 0)
    if [[ $COLORS -ge 8 ]]; then
        # Standard colors
        RED=$(tput setaf 1)
        GREEN=$(tput setaf 2)
        YELLOW=$(tput setaf 3)
        BLUE=$(tput setaf 4)
        MAGENTA=$(tput setaf 5)
        CYAN=$(tput setaf 6)
        WHITE=$(tput setaf 7)

        # Bright colors
        BRIGHT_GREEN=$(tput setaf 10 2>/dev/null || tput setaf 2)
        BRIGHT_YELLOW=$(tput setaf 11 2>/dev/null || tput setaf 3)
        BRIGHT_BLUE=$(tput setaf 12 2>/dev/null || tput setaf 4)
        BRIGHT_MAGENTA=$(tput setaf 13 2>/dev/null || tput setaf 5)
        BRIGHT_CYAN=$(tput setaf 14 2>/dev/null || tput setaf 6)

        # Text formatting
        BOLD=$(tput bold)
        DIM=$(tput dim 2>/dev/null || echo "")
        RESET=$(tput sgr0)
    else
        RED="" GREEN="" YELLOW="" BLUE="" MAGENTA="" CYAN="" WHITE=""
        BRIGHT_GREEN="" BRIGHT_YELLOW="" BRIGHT_BLUE="" BRIGHT_MAGENTA="" BRIGHT_CYAN=""
        BOLD="" DIM="" RESET=""
    fi
else
    RED="" GREEN="" YELLOW="" BLUE="" MAGENTA="" CYAN="" WHITE=""
    BRIGHT_GREEN="" BRIGHT_YELLOW="" BRIGHT_BLUE="" BRIGHT_MAGENTA="" BRIGHT_CYAN=""
    BOLD="" DIM="" RESET=""
fi

# ============================================================================
# Logging Functions
# ============================================================================

log_info() {
    echo -e "${BRIGHT_BLUE}${BOLD}ℹ${RESET} ${CYAN}$*${RESET}" >&2
}

log_success() {
    echo -e "${BRIGHT_GREEN}${BOLD}✓${RESET} ${GREEN}$*${RESET}" >&2
}

log_warning() {
    echo -e "${BRIGHT_YELLOW}${BOLD}⚠${RESET} ${YELLOW}$*${RESET}" >&2
}

log_error() {
    echo -e "${RED}${BOLD}✗${RESET} ${RED}$*${RESET}" >&2
}

log_step() {
    echo -e "${BRIGHT_MAGENTA}${BOLD}▸${RESET} ${MAGENTA}$*${RESET}" >&2
}

log_header() {
    local text="$*"
    local length=${#text}
    local line=$(printf '═%.0s' $(seq 1 $length))
    echo "" >&2
    echo -e "${BRIGHT_CYAN}${BOLD}╔${line}╗${RESET}" >&2
    echo -e "${BRIGHT_CYAN}${BOLD}║${RESET}${BOLD}${WHITE}${text}${RESET}${BRIGHT_CYAN}${BOLD}║${RESET}" >&2
    echo -e "${BRIGHT_CYAN}${BOLD}╚${line}╝${RESET}" >&2
    echo "" >&2
}

log_data() {
    local label="$1"
    local value="$2"
    echo -e "  ${DIM}${label}:${RESET} ${BOLD}${value}${RESET}" >&2
}

# ============================================================================
# Helper Functions
# ============================================================================

check_dependencies() {
    local missing=()

    if ! command -v gh &> /dev/null; then
        missing+=("gh (GitHub CLI)")
    fi

    if ! command -v jq &> /dev/null; then
        missing+=("jq")
    fi

    if ! command -v unzip &> /dev/null; then
        missing+=("unzip")
    fi

    if [[ ${#missing[@]} -gt 0 ]]; then
        log_error "Missing required dependencies:"
        for dep in "${missing[@]}"; do
            echo -e "  ${RED}•${RESET} ${dep}"
        done
        exit 1
    fi
}

check_gh_auth() {
    if ! gh auth status &> /dev/null; then
        log_error "Not authenticated with GitHub CLI"
        log_info "Run: ${BOLD}gh auth login${RESET}"
        exit 1
    fi
}

show_help() {
    cat << EOF
${BOLD}${BRIGHT_CYAN}GitHub Artifact Downloader${RESET}

${BOLD}USAGE:${RESET}
    $(basename "$0") ${CYAN}<REPO>${RESET} [${YELLOW}OPTIONS${RESET}]

${BOLD}ARGUMENTS:${RESET}
    ${CYAN}REPO${RESET}                GitHub repository (${DIM}owner/repo${RESET})

${BOLD}OPTIONS:${RESET}
    ${YELLOW}-n, --name NAME${RESET}     Artifact name to download (preselect)
    ${YELLOW}-o, --output DIR${RESET}    Output directory (default: current directory)
    ${YELLOW}-h, --help${RESET}          Show this help message

${BOLD}EXAMPLES:${RESET}
    ${DIM}# Interactive mode - list and select artifacts${RESET}
    $(basename "$0") valknarness/awesome

    ${DIM}# Preselect artifact by name${RESET}
    $(basename "$0") valknarness/awesome -n awesome-database-latest

    ${DIM}# Download to specific directory${RESET}
    $(basename "$0") valknarness/awesome -o ~/downloads

    ${DIM}# Combine options${RESET}
    $(basename "$0") valknarness/awesome -n awesome-database-latest -o ~/downloads

EOF
}

format_size() {
    local bytes=$1
    if (( bytes < 1024 )); then
        echo "${bytes}B"
    elif (( bytes < 1048576 )); then
        awk "BEGIN {printf \"%.1fKB\", $bytes/1024}"
    elif (( bytes < 1073741824 )); then
        awk "BEGIN {printf \"%.1fMB\", $bytes/1048576}"
    else
        awk "BEGIN {printf \"%.2fGB\", $bytes/1073741824}"
    fi
}

format_date() {
    local iso_date="$1"
    if command -v date &> /dev/null; then
        if date --version &> /dev/null 2>&1; then
            # GNU date
            date -d "$iso_date" "+%Y-%m-%d %H:%M:%S" 2>/dev/null || echo "$iso_date"
        else
            # BSD date (macOS)
            date -j -f "%Y-%m-%dT%H:%M:%SZ" "$iso_date" "+%Y-%m-%d %H:%M:%S" 2>/dev/null || echo "$iso_date"
        fi
    else
        echo "$iso_date"
    fi
}

# ============================================================================
# Main Functions
# ============================================================================

list_artifacts() {
    local repo="$1"

    log_step "Fetching artifacts from ${BOLD}${repo}${RESET}..."

    # First check if there are any artifacts using gh's built-in jq
    local count
    count=$(gh api \
        -H "Accept: application/vnd.github+json" \
        -H "X-GitHub-Api-Version: 2022-11-28" \
        --jq '.artifacts | length' \
        "/repos/${repo}/actions/artifacts?per_page=100" 2>/dev/null)

    if [[ -z "$count" ]]; then
        log_error "Failed to fetch artifacts from repository"
        log_info "Please check that:"
        echo "  • The repository ${BOLD}${repo}${RESET} exists and you have access"
        echo "  • GitHub Actions is enabled for this repository"
        exit 1
    fi

    if [[ "$count" -eq 0 ]]; then
        log_warning "No artifacts found in repository ${BOLD}${repo}${RESET}"
        log_info "This repository may not have any workflow runs that produced artifacts"
        exit 0
    fi

    # Now fetch the full JSON response
    local artifacts_json
    artifacts_json=$(gh api \
        -H "Accept: application/vnd.github+json" \
        -H "X-GitHub-Api-Version: 2022-11-28" \
        "/repos/${repo}/actions/artifacts?per_page=100" 2>/dev/null)

    echo "$artifacts_json"
}

select_artifact() {
    local artifacts_json="$1"
    local preselect_name="$2"

    # Parse artifacts
    local artifacts
    artifacts=$(echo "$artifacts_json" | jq -r '.artifacts[] |
        "\(.id)|\(.name)|\(.size_in_bytes)|\(.created_at)|\(.workflow_run.id)"')

    # If preselect name is provided, find matching artifact
    if [[ -n "$preselect_name" ]]; then
        local selected
        selected=$(echo "$artifacts" | grep -F "|${preselect_name}|" | head -1)

        if [[ -z "$selected" ]]; then
            log_error "Artifact '${BOLD}${preselect_name}${RESET}' not found"
            log_info "Available artifacts:"
            echo "$artifacts" | while IFS='|' read -r id name size created workflow; do
                echo "  ${CYAN}•${RESET} ${name}"
            done
            exit 1
        fi

        echo "$selected"
        return 0
    fi

    # Interactive selection
    log_info "Available artifacts:"
    echo ""

    local i=1
    local -a artifact_array

    while IFS='|' read -r id name size created workflow; do
        artifact_array+=("$id|$name|$size|$created|$workflow")
        local formatted_size=$(format_size "$size")
        local formatted_date=$(format_date "$created")

        printf "  ${BOLD}${YELLOW}[%2d]${RESET} ${BRIGHT_CYAN}%s${RESET}\n" "$i" "$name"
        printf "       ${DIM}Size: ${RESET}%s  ${DIM}Created: ${RESET}%s\n" "$formatted_size" "$formatted_date"
        echo ""

        ((i++))
    done <<< "$artifacts"

    # Prompt for selection
    local selection
    while true; do
        echo -n -e "${BRIGHT_MAGENTA}${BOLD}�${RESET} ${MAGENTA}Select artifact [1-$((i-1))]:${RESET} "
        read -r selection

        if [[ "$selection" =~ ^[0-9]+$ ]] && [[ "$selection" -ge 1 ]] && [[ "$selection" -lt "$i" ]]; then
            break
        else
            log_warning "Invalid selection. Please enter a number between 1 and $((i-1))"
        fi
    done

    echo "${artifact_array[$((selection-1))]}"
}

download_artifact() {
    local repo="$1"
    local artifact_id="$2"
    local artifact_name="$3"
    local output_dir="$4"

    log_step "Downloading artifact ${BOLD}${artifact_name}${RESET}..."

    # Create output directory if it doesn't exist
    mkdir -p "$output_dir"

    # Download artifact using gh
    local zip_file="${output_dir}/${artifact_name}.zip"

    if gh api \
        -H "Accept: application/vnd.github+json" \
        -H "X-GitHub-Api-Version: 2022-11-28" \
        "/repos/${repo}/actions/artifacts/${artifact_id}/zip" \
        > "$zip_file" 2>/dev/null; then

        log_success "Downloaded to ${BOLD}${zip_file}${RESET}"
        echo "$zip_file"
    else
        log_error "Failed to download artifact"
        exit 1
    fi
}

extract_artifact() {
    local zip_file="$1"
    local output_dir="$2"

    log_step "Extracting archive..."

    # Create extraction directory
    local extract_dir="${output_dir}/$(basename "$zip_file" .zip)"
    mkdir -p "$extract_dir"

    if unzip -q "$zip_file" -d "$extract_dir"; then
        log_success "Extracted to ${BOLD}${extract_dir}${RESET}"

        # Show extracted files
        log_info "Extracted files:"
        find "$extract_dir" -type f -exec basename {} \; | while read -r file; do
            echo "  ${GREEN}•${RESET} ${file}"
        done

        # Remove zip file
        rm "$zip_file"
        log_info "Cleaned up zip file"

        echo "$extract_dir"
    else
        log_error "Failed to extract archive"
        exit 1
    fi
}

# ============================================================================
# Main Script
# ============================================================================

main() {
    local repo=""
    local artifact_name=""
    local output_dir="."

    # Parse arguments
    while [[ $# -gt 0 ]]; do
        case $1 in
            -h|--help)
                show_help
                exit 0
                ;;
            -n|--name)
                artifact_name="$2"
                shift 2
                ;;
            -o|--output)
                output_dir="$2"
                shift 2
                ;;
            -*)
                log_error "Unknown option: $1"
                echo ""
                show_help
                exit 1
                ;;
            *)
                if [[ -z "$repo" ]]; then
                    repo="$1"
                else
                    log_error "Unexpected argument: $1"
                    echo ""
                    show_help
                    exit 1
                fi
                shift
                ;;
        esac
    done

    # Validate required arguments
    if [[ -z "$repo" ]]; then
        log_error "Repository argument is required"
        echo ""
        show_help
        exit 1
    fi

    # Validate repository format
    if [[ ! "$repo" =~ ^[^/]+/[^/]+$ ]]; then
        log_error "Invalid repository format. Expected: ${BOLD}owner/repo${RESET}"
        exit 1
    fi

    # Show header
    log_header "GitHub Artifact Downloader"

    # Check dependencies
    log_step "Checking dependencies..."
    check_dependencies
    log_success "All dependencies found"

    # Check GitHub authentication
    log_step "Checking GitHub authentication..."
    check_gh_auth
    log_success "Authenticated with GitHub"

    echo ""
    log_data "Repository" "${BRIGHT_CYAN}${repo}${RESET}"
    if [[ -n "$artifact_name" ]]; then
        log_data "Artifact" "${BRIGHT_YELLOW}${artifact_name}${RESET}"
    fi
    log_data "Output" "${BRIGHT_GREEN}${output_dir}${RESET}"
    echo ""

    # List artifacts
    local artifacts_json
    artifacts_json=$(list_artifacts "$repo")

    # Select artifact
    local selected
    selected=$(select_artifact "$artifacts_json" "$artifact_name")

    IFS='|' read -r artifact_id name size created workflow <<< "$selected"

    echo ""
    log_info "Selected artifact:"
    log_data "  Name" "${BRIGHT_CYAN}${name}${RESET}"
    log_data "  Size" "$(format_size "$size")"
    log_data "  Created" "$(format_date "$created")"
    echo ""

    # Download artifact
    local zip_file
    zip_file=$(download_artifact "$repo" "$artifact_id" "$name" "$output_dir")

    # Extract artifact
    local extract_dir
    extract_dir=$(extract_artifact "$zip_file" "$output_dir")

    # Success summary
    echo ""
    log_header "Download Complete!"
    log_data "Location" "${BOLD}${extract_dir}${RESET}"
    echo ""

    log_success "All done! 🎉"
}

# Run main function
main "$@"
