#!/bin/bash
set -uo pipefail  # Remove -e to handle errors manually
SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )"

# Arrays to track results
declare -A BUILD_RESULTS
declare -A TEST_RESULTS
declare -A PUBLISH_RESULTS
declare -a PROJECTS
OVERALL_SUCCESS=true

function dothis() {
    local thisthing="$1"
    local dir="$2"
    local project="$3"

    cmd=""

    [ ! -f "${dir}/${thisthing}.sh" ] || cmd="${dir}/${thisthing}.sh"
    [ ! -f "${dir}/${thisthing}" ] || cmd="${dir}/${thisthing}"

    if [ -z "$cmd" ]; then
        echo "No ${thisthing} script found in $dir"
        case "$thisthing" in
            build) BUILD_RESULTS["$project"]="SKIP" ;;
            test) TEST_RESULTS["$project"]="SKIP" ;;
            publish) PUBLISH_RESULTS["$project"]="SKIP" ;;
        esac
        return 0
    else
        echo "Running $cmd"
        if "$cmd"; then
            case "$thisthing" in
                build) BUILD_RESULTS["$project"]="✓" ;;
                test) TEST_RESULTS["$project"]="✓" ;;
                publish) PUBLISH_RESULTS["$project"]="✓" ;;
            esac
            return 0
        else
            case "$thisthing" in
                build) BUILD_RESULTS["$project"]="✗" ;;
                test) TEST_RESULTS["$project"]="✗" ;;
                publish) PUBLISH_RESULTS["$project"]="✗" ;;
            esac
            OVERALL_SUCCESS=false
            return 1
        fi
    fi
}

function title() {
    local title="$1"
    local inner_width=59  # Width between the borders (box_width - 2)
    
    # Get the actual display width (handles emojis correctly)
    local title_display_width
    title_display_width=$(echo -n "$title" | wc -L)
    
    # Calculate total padding needed
    local total_padding=$(( inner_width - title_display_width ))
    local left_padding=$(( total_padding / 2 ))
    local right_padding=$(( total_padding - left_padding ))
    
    # Top border
    echo
    printf "╔"
    printf "═%.0s" $(seq 1 $inner_width)
    printf "╗\n"
    
    # Empty line
    printf "║%*s║\n" $inner_width ""
    
    # Title line with padding
    printf "║%*s%s%*s║\n" $left_padding "" "$title" $right_padding ""
    
    # Empty line
    printf "║%*s║\n" $inner_width ""
    
    # Bottom border
    printf "╚"
    printf "═%.0s" $(seq 1 $inner_width)
    printf "╝\n"
    echo
}

function subtitle() {
    local subtitle="$1"
    echo " "
    echo "--------------------------------"
    echo "$subtitle"
    echo " "
}

function buildtestpublish() {
    local dir="$1"

    TOOLNAME=$(basename "$dir")
    TOOLNAME_UPPER=$(echo "$TOOLNAME" | tr '[:lower:]' '[:upper:]')
    title "🔧 $TOOLNAME_UPPER 🔧"

    export PROJECT="$TOOLNAME_UPPER"

    # Add to projects list
    PROJECTS+=("$TOOLNAME")

    cd "$dir" || echo "Failed to cd to $dir"

    subtitle "🔨 BUILDING $TOOLNAME_UPPER 🔨"
    dothis build "$dir" "$TOOLNAME"

    subtitle "🔍 TESTING $TOOLNAME_UPPER 🔍"
    dothis test "$dir" "$TOOLNAME"

    subtitle "📦 PUBLISHING $TOOLNAME_UPPER 📦"
    dothis publish "$dir" "$TOOLNAME"

    echo "Done"
}

function buildtestpublish_all() {
    PREVIOUS_DIR=$(pwd)

    # Create array of directories to avoid subshell issues with while loop
    local dirs=()
    while IFS= read -r -d '' dir; do
        dirs+=("$dir")
    done < <(find "$SCRIPT_DIR" -maxdepth 1 -type d \
        -not -name ".*" \
        -not -path "$SCRIPT_DIR" \
        -print0)

    # Process each directory
    for dir in "${dirs[@]}"; do
        buildtestpublish "${dir}" || true  # Continue even if one project fails
    done

    cd "$PREVIOUS_DIR" || echo "Failed to cd to $PREVIOUS_DIR"
}

function print_summary() {
    title "📊 BUILD SUMMARY 📊"
    
    # Calculate column widths
    local max_project_width=7  # "PROJECT" header
    for project in "${PROJECTS[@]}"; do
        if [ "${#project}" -gt "$max_project_width" ]; then
            max_project_width=${#project}
        fi
    done
    
    # Add padding
    max_project_width=$((max_project_width + 2))
    
    # Print header
    printf "┌"
    printf "─%.0s" $(seq 1 $((max_project_width + 2)))
    printf "┬─────────┬─────────┬─────────┐\n"
    printf "│ %-*s │ %-7s │ %-7s │ %-7s │\n" $max_project_width "PROJECT" "BUILD" "TEST" "PUBLISH"
    printf "├"
    printf "─%.0s" $(seq 1 $((max_project_width + 2)))
    printf "┼─────────┼─────────┼─────────┤\n"
    
    # Print results for each project
    for project in "${PROJECTS[@]}"; do
        local build_status="${BUILD_RESULTS[$project]:-'-'}"
        local test_status="${TEST_RESULTS[$project]:-'-'}"
        local publish_status="${PUBLISH_RESULTS[$project]:-'-'}"
        
        printf "│ %-*s │ %-7s │ %-7s │ %-7s │\n" \
            $max_project_width "$project" \
            "$build_status" "$test_status" "$publish_status"
    done
    
    # Print bottom border
    printf "└"
    printf "─%.0s" $(seq 1 $((max_project_width + 2)))
    printf "┴─────────┴─────────┴─────────┘\n"
    
    echo
}

title "🔨 BUILDING ALL TOOLS 🔨"

getpkg/build.sh
export GETPKG="${SCRIPT_DIR}/getpkg/output/getpkg"
if [ ! -f "$GETPKG" ]; then
    echo "Build failed."
    exit 1
fi

buildtestpublish_all

print_summary

if [ "$OVERALL_SUCCESS" = true ]; then
    title "🚀 Deployment Complete! 🚀"
    exit 0
else
    title "❌ Deployment Failed! ❌"
    exit 1
fi