#!/usr/bin/env bash
# build.sh — Build and install native-hello-ios to the iOS Simulator.
#
# Usage:
#   ./build.sh           # gen C sources + xcodebuild for simulator
#   ./build.sh gen       # regenerate C sources only
#   ./build.sh build     # xcodebuild only (skip elc step)
#   ./build.sh install   # gen + build + boot simulator + install + launch
#   ./build.sh clean     # remove build/ directory
#
# Requirements:
#   - Xcode with iOS Simulator SDK installed
#   - elc at ../../../lang/dist/platform/elc (or in PATH)

set -euo pipefail

SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
EL_LANG_ROOT="${SCRIPT_DIR}/../../../lang"
EL_UI_ROOT="${SCRIPT_DIR}/../.."
EL_RUNTIME="${EL_LANG_ROOT}/runtime"
EL_NATIVE_VESSEL="${EL_UI_ROOT}/vessels/el-native/src/main.el"
EL_APP_ENTRY="${EL_UI_ROOT}/examples/native-hello/src/main.el"
EL_MANIFEST="${EL_UI_ROOT}/examples/native-hello/manifest.el"
SOURCES_DIR="${SCRIPT_DIR}/NativeHello"
BUILD_DIR="${SCRIPT_DIR}/build"

# Locate elc.
if command -v elc &>/dev/null; then
    ELC="elc"
elif [ -x "${EL_LANG_ROOT}/dist/platform/elc" ]; then
    ELC="${EL_LANG_ROOT}/dist/platform/elc"
else
    echo "Error: elc not found. Add it to PATH or place it at:"
    echo "  ${EL_LANG_ROOT}/dist/platform/elc"
    exit 1
fi

gen() {
    echo "==> Generating native_hello.c..."
    EL_MANIFEST="${EL_MANIFEST}" \
        "${ELC}" "${EL_APP_ENTRY}" \
        > "${SOURCES_DIR}/native_hello.c"
    # Rename the compiled el main() to el_app_main so it doesn't conflict with
    # main.m's main(). main.m's main() is the real entry point for UIApplicationMain.
    # Use a simple sed substitution on the exact signature elc emits.
    sed -i '' 's/^int main(int _argc, char\*\* _argv) {/int el_app_main(int _argc, char** _argv) {/' \
        "${SOURCES_DIR}/native_hello.c"

    echo "==> Generating el_native_vessel.c..."
    "${ELC}" "${EL_NATIVE_VESSEL}" \
        > "${SOURCES_DIR}/el_native_vessel.c"
    # Rename vessel main() similarly.
    sed -i '' 's/^int main(int _argc, char\*\* _argv) {/int el_vessel_main(int _argc, char** _argv) {/' \
        "${SOURCES_DIR}/el_native_vessel.c"

    echo "==> Copying runtime files..."
    cp "${EL_RUNTIME}/el_uikit.m"         "${SOURCES_DIR}/"
    cp "${EL_RUNTIME}/el_seed.c"          "${SOURCES_DIR}/"
    cp "${EL_RUNTIME}/el_runtime.c"       "${SOURCES_DIR}/"
    cp "${EL_RUNTIME}/el_runtime.h"       "${SOURCES_DIR}/"
    cp "${EL_RUNTIME}/el_native_target.h" "${SOURCES_DIR}/"

    echo "==> Source generation complete."
}

xcode_build() {
    echo "==> Building with xcodebuild (iphonesimulator)..."
    xcodebuild \
        -project "${SCRIPT_DIR}/NativeHello.xcodeproj" \
        -scheme NativeHello \
        -sdk iphonesimulator \
        -configuration Debug \
        -derivedDataPath "${BUILD_DIR}" \
        CLANG_ENABLE_OBJC_ARC=NO \
        OTHER_CFLAGS="-DEL_TARGET_IOS" \
        OTHER_LDFLAGS="-ldl" \
        build

    APP_PATH=$(find "${BUILD_DIR}" -name "NativeHello.app" -maxdepth 6 | head -1)
    if [ -n "${APP_PATH}" ]; then
        echo "==> Build complete."
        echo "    App bundle: ${APP_PATH}"
    else
        echo "==> Build complete (app bundle in ${BUILD_DIR})."
    fi
}

install_and_launch() {
    gen
    xcode_build

    APP_PATH=$(find "${BUILD_DIR}" -name "NativeHello.app" -maxdepth 6 | head -1)
    if [ -z "${APP_PATH}" ]; then
        echo "Error: could not find NativeHello.app in ${BUILD_DIR}"
        exit 1
    fi

    # Boot the default simulator if not already booted.
    SIM_UDID=$(xcrun simctl list devices available --json \
        | python3 -c "
import json,sys
d=json.load(sys.stdin)['devices']
for runtime,devs in d.items():
    for dev in devs:
        if 'iPhone' in dev['name'] and dev['isAvailable']:
            print(dev['udid'])
            exit()
")
    if [ -z "${SIM_UDID}" ]; then
        echo "Error: no available iPhone simulator found."
        exit 1
    fi
    echo "==> Using simulator: ${SIM_UDID}"
    xcrun simctl boot "${SIM_UDID}" 2>/dev/null || true
    open -a Simulator

    echo "==> Installing app..."
    xcrun simctl install "${SIM_UDID}" "${APP_PATH}"

    echo "==> Launching app..."
    xcrun simctl launch "${SIM_UDID}" "ai.neurontechnologies.el.nativehello"
}

clean() {
    echo "==> Cleaning..."
    rm -rf "${BUILD_DIR}"
    echo "==> Clean complete."
}

case "${1:-all}" in
    gen)     gen ;;
    build)   xcode_build ;;
    install) install_and_launch ;;
    clean)   clean ;;
    all|*)   gen && xcode_build ;;
esac
