#!/bin/bash -eu
# SPDX-FileCopyrightText: 2025 Uwe Fechner
# SPDX-License-Identifier: MIT

julia_version=""
_yes_to_all=false

export JULIA_PKG_SERVER_REGISTRY_PREFERENCE=eager

# Parse command line arguments
while [[ $# -gt 0 ]]; do
    case $1 in
        --version)
            if [[ $# -lt 2 ]]; then
                echo "Error: --version requires a version argument"
                exit 1
            fi
            julia_version="$2"
            shift 2
            ;;
        -y|--yes)
            _yes_to_all=true
            shift
            ;;
        *)
            echo "Invalid parameter! Use:"
            echo "./create_sys_image"
            echo "or"
            echo "./create_sys_image --version 1.x"
            echo "or"
            echo "./create_sys_image -y"
            echo "or"
            echo "./create_sys_image --yes"
            exit 1
            ;;
    esac
done

if [[ -n "$julia_version" ]]; then
    JULIA_CMD="julia +$julia_version"
else
    JULIA_CMD="julia"
fi

if [[ $(basename $(pwd)) == "bin" ]]; then
    cd ..
fi

# disable pre-compilation
cp LocalPreferences.toml.default LocalPreferences.toml

export JULIA_PKG_SERVER_REGISTRY_PREFERENCE="eager"

if ! command -v juliaup &> /dev/null; then
    echo "Please install the Julia installer 'juliaup'!"
    echo "See: https://github.com/JuliaLang/juliaup"
    exit 1
fi

# if julia is not installed, install Julia 1.11
if ! command -v julia &> /dev/null; then
    juliaup add 1.11
    juliaup default 1.11
fi

PYTHON_PATH=$(which python3)
if [ -x "$PYTHON_PATH" ]; then
    echo "Python is found at $PYTHON_PATH"
    if $PYTHON_PATH -c "import matplotlib" &> /dev/null; then
        echo "Matplotlib found. Using existing installation."
        export PYTHON=$PYTHON_PATH
    else
        echo "Matplotlib is not found."
        if [[ $_yes_to_all == true ]]; then
            echo "Installing matplotlib with Conda..."
            export PYTHON=""
        else
            read -p "Do you want to install matplotlib with Conda? (y/n): " choice
            case "$choice" in 
              y|Y ) 
                export PYTHON=""
                ;;
              n|N ) 
                echo "Exiting without installing matplotlib."
                exit 1
                ;;
              * ) 
                echo "Invalid choice. Exiting."
                exit 1
                ;;
            esac
        fi
    fi
else
    echo "Python is not found."
    exit 1
fi

# Check memory and limit threads if needed
if [[ "$OSTYPE" == "msys" || "$OSTYPE" == "win32" ]]; then
    # Windows: use wmic or PowerShell
    echo "Checking system memory on Windows..."
    totalmem=$(powershell.exe -Command "(Get-CimInstance Win32_ComputerSystem).TotalPhysicalMemory / 1MB" 2>/dev/null | awk '{printf "%i", $1}')
    if [[ -z "$totalmem" || $totalmem -lt 27000 ]]; then
        echo "Warning: Less than 27GB of memory detected on Windows. Using only one thread for sysimage compilation."
        export JULIA_IMAGE_THREADS=1
    fi
elif [[ "$OSTYPE" == darwin* ]]; then
    # macOS: use sysctl
    echo "Checking system memory on macOS..."
    totalmem=$(sysctl -n hw.memsize 2>/dev/null | awk '{printf "%i", $1 / 1000000}')
    if [[ -z "$totalmem" || $totalmem -lt 27000 ]]; then
        echo "Warning: Less than 27GB of memory detected on macOS. Using only one thread for sysimage compilation."
        export JULIA_IMAGE_THREADS=1
    fi
else
    # Linux: use /proc/meminfo
    totalmem=$(grep MemTotal /proc/meminfo | awk '{printf "%i", $2 / 1024}')
    if [[ $totalmem -lt 26674 ]]; then
        echo "Warning: Less than 27GB of memory detected. Using only one thread for sysimage compilation."
        export JULIA_IMAGE_THREADS=1
    fi
fi

julia_version=$($JULIA_CMD --version | awk '{print($3)}')
julia_major=${julia_version:0:3}
if [[ $julia_major == "1.1" ]]; then
    julia_major=${julia_version:0:4} 
fi
if [ -d .git ] || git rev-parse --git-dir > /dev/null 2>&1 ; then
    branch=$(git rev-parse --abbrev-ref HEAD | sed 's/\//-/g')
else
    branch=""
fi
if test -f "kps-image-${julia_major}-${branch}.so"; then
    mv bin/kps-image-${julia_major}-${branch}.so kps-image-${julia_major}-${branch}.so.bak
fi

if [[ $julia_major == "1.10" ]]; then
    rm -f data/model_1.10_*.bin.default
    rm -f data/model_1.10_*.bin
elif [[ $julia_major == "1.11" ]]; then
    rm -f data/model_1.11_*.bin.default
    rm -f data/model_1.11_*.bin
else
    rm -f data/model_1.12_*.bin.default
    rm -f data/model_1.12_*.bin
fi

if [[ $julia_major == "1.10" ]]; then
    cp Manifest-v1.10.toml.default Manifest-v1.10.toml
    echo "Using Manifest-v1.10.toml.default ..."        
elif [[ $julia_major == "1.11" ]]; then
    cp Manifest-v1.11.toml.default Manifest-v1.11.toml
    echo "Using Manifest-v1.11.toml.default ..."
else
    cp Manifest-v1.12.toml.default Manifest-v1.12.toml
    echo "Using Manifest-v1.12.toml.default ..."
fi

$JULIA_CMD --startup-file=no --project -e "using Pkg; Pkg.instantiate();"
# Seed sub-project manifests from main manifest and resolve
rm -f examples/Manifest*.toml examples_3d/Manifest*.toml test/Manifest*.toml
cp "Manifest-v${julia_major}.toml" "examples/Manifest-v${julia_major}.toml"
cp "Manifest-v${julia_major}.toml" "examples_3d/Manifest-v${julia_major}.toml"
cp "Manifest-v${julia_major}.toml" "test/Manifest-v${julia_major}.toml"
$JULIA_CMD --startup-file=no --project -e "using Pkg; Pkg.activate(\"examples\"); Pkg.resolve(); Pkg.instantiate();"
if [ -f "examples/Manifest.toml" ]; then
    mv examples/Manifest.toml examples/Manifest-v${julia_major}.toml
fi
$JULIA_CMD --startup-file=no --project -e "using Pkg; Pkg.activate(\"examples_3d\"); Pkg.resolve(); Pkg.instantiate();"
if [ -f "examples_3d/Manifest.toml" ]; then
    mv examples_3d/Manifest.toml examples_3d/Manifest-v${julia_major}.toml
fi
$JULIA_CMD --startup-file=no --project -e "using Pkg; Pkg.activate(\"test\"); Pkg.resolve(); Pkg.instantiate();"
if [ -f "test/Manifest.toml" ]; then
    mv test/Manifest.toml test/Manifest-v${julia_major}.toml
fi
# Resolve docs independently (different dep tree; seeding from main causes missing extensions)
rm -f docs/Manifest*.toml
$JULIA_CMD --startup-file=no --project -e "using Pkg; Pkg.activate(\"docs\"); Pkg.resolve(); Pkg.instantiate();"
if [ -f "docs/Manifest.toml" ]; then
    mv docs/Manifest.toml docs/Manifest-v${julia_major}.toml
fi
$JULIA_CMD --startup-file=no --heap-size-hint=8000M --project -e "using Pkg; Pkg.activate(\"test\"); include(\"./test/create_sys_image.jl\");"

if [[ $branch != "" ]]; then
    SOFILE="bin/kps-image-${julia_major}-${branch}.so"
else
    SOFILE="bin/kps-image-${julia_major}.so"
fi
if test -f $SOFILE; then
    mv $SOFILE $SOFILE.bak
fi
mv kps-image_tmp.so $SOFILE
$JULIA_CMD --startup-file=no  --project -e "using Pkg; Pkg.precompile()"

# enable pre-compilation
rm LocalPreferences.toml
echo "Precompiling package KiteModels..."
$JULIA_CMD --startup-file=no --project -J $SOFILE -e "using KiteModels, KitePodModels, KiteUtils"
echo "Precompiling package ControlPlots ..."
if [[ $branch != "" ]]; then
    $JULIA_CMD --startup-file=no --project -J $SOFILE -e "using Pkg; Pkg.activate(\"test\"); using ControlPlots, KiteModels"
else
    $JULIA_CMD --startup-file=no --project -J $SOFILE -e "using ControlPlots, KiteModels"
fi
julia --project=docs -J bin/kps-image-${julia_major}-${branch}.so -e "using LiveServer, Documenter, Pkg; Pkg.instantiate()"

