#!/bin/bash
set -e

echo "Building Hypen Engine for WASM..."

# Check if wasm-pack is installed
if ! command -v wasm-pack &> /dev/null; then
    echo "wasm-pack not found. Installing..."
    cargo install wasm-pack
fi

# ==============================================================================
# JavaScript Builds (wasm-bindgen)
# ==============================================================================

echo ""
echo "=== JavaScript Runtime Builds (wasm-bindgen) ==="
echo ""

# Build for web (bundler)
echo "Building for web (bundler)..."
wasm-pack build --target bundler --out-dir pkg/bundler --features js

# Build for node.js
echo "Building for Node.js..."
wasm-pack build --target nodejs --out-dir pkg/nodejs --features js

# Build for web (no bundler)
echo "Building for web (no bundler)..."
wasm-pack build --target web --out-dir pkg/web --features js

# Build for browser (alias for web, but keeps imports consistent)
echo "Building for browser..."
wasm-pack build --target web --out-dir pkg/browser --features js

# ==============================================================================
# WASI Build (C FFI)
# ==============================================================================

echo ""
echo "=== WASI Runtime Build (C FFI) ==="
echo ""

# Check if wasm32-wasip1 target is installed (was wasm32-wasi before Rust 1.78)
if ! rustup target list --installed | grep -q wasm32-wasip1; then
    echo "Installing wasm32-wasip1 target..."
    rustup target add wasm32-wasip1
fi

# Build for WASI
echo "Building for WASI..."
cargo build --target wasm32-wasip1 --release --features wasi

# Create output directory
mkdir -p pkg/wasi

# Copy the WASM file
cp target/wasm32-wasip1/release/hypen_engine.wasm pkg/wasi/

# Copy the WIT interface file
cp wit/hypen.wit pkg/wasi/

# Create a simple README for the WASI package
cat > pkg/wasi/README.md << 'EOF'
# Hypen Engine WASI Module

This is a WASI-compatible build of the Hypen Engine for use with non-JavaScript
WASM runtimes like Go (wasmtime-go, wazero), Python (wasmtime, wasmer), and others.

## Files

- `hypen_engine.wasm` - The WASM module with C FFI exports
- `hypen.wit` - WIT interface definition for Component Model support

## FFI Functions

All functions use a C-compatible ABI with string data passed as (ptr, len) pairs.
Data is exchanged as JSON strings.

### Memory Management
- `wasi_alloc(size) -> ptr` - Allocate memory
- `wasi_free(ptr, size)` - Free memory

### Lifecycle
- `hypen_init() -> status` - Initialize engine
- `hypen_destroy()` - Destroy engine
- `hypen_get_revision() -> u64` - Get revision number

### Rendering
- `hypen_render_source(source_ptr, source_len) -> status` - Render Hypen DSL
- `hypen_render_into(source_ptr, len, parent_ptr, len, state_ptr, len) -> status`

### State
- `hypen_update_state(patch_ptr, patch_len) -> status` - Update state
- `hypen_update_state_sparse(update_ptr, update_len) -> status` - Sparse update

### Module
- `hypen_set_module(config_ptr, config_len) -> status` - Set module config

### Actions
- `hypen_register_action(name_ptr, name_len) -> status` - Register action
- `hypen_dispatch_action(action_ptr, action_len) -> status` - Dispatch action

### Components
- `hypen_register_primitive(name_ptr, name_len) -> status` - Register primitive
- `hypen_register_component(name_ptr, len, source_ptr, len, path_ptr, len) -> status`

### Buffers (for retrieving results)
- `hypen_get_patches_len() -> usize` - Get patches buffer size
- `hypen_get_patches(out_ptr, out_len) -> bytes_copied` - Copy patches to buffer
- `hypen_clear_patches()` - Clear patches buffer
- `hypen_get_action_len() -> usize` - Get action buffer size
- `hypen_get_action(out_ptr, out_len) -> bytes_copied` - Copy action to buffer
- `hypen_clear_action()` - Clear action buffer

## Example (Go with wasmtime-go)

```go
// Load the WASM module
engine := wasmtime.NewEngine()
module, _ := wasmtime.NewModuleFromFile(engine, "hypen_engine.wasm")

// Create instance and call functions
// ... (see wasmtime-go documentation)
```

## Example (Python with wasmtime)

```python
from wasmtime import Store, Module, Instance

store = Store()
module = Module.from_file(store.engine, "hypen_engine.wasm")
instance = Instance(store, module, [])

# Get exports
init = instance.exports(store)["hypen_init"]
init(store)
```
EOF

echo ""
echo "=== Copying WASM to SDK locations ==="
echo ""

SDK_DIR="../hypen-web/packages/core"

if [ -d "$SDK_DIR" ]; then
  # Copy Node.js build to SDK wasm-node/
  if [ -d "pkg/nodejs" ] && [ -d "$SDK_DIR/wasm-node" ]; then
    cp pkg/nodejs/* "$SDK_DIR/wasm-node/"
    echo "  Copied pkg/nodejs/ -> $SDK_DIR/wasm-node/"
  fi

  # Copy Web build to SDK wasm-browser/
  if [ -d "pkg/web" ] && [ -d "$SDK_DIR/wasm-browser" ]; then
    cp pkg/web/* "$SDK_DIR/wasm-browser/"
    echo "  Copied pkg/web/ -> $SDK_DIR/wasm-browser/"
  fi
else
  echo "  WARNING: SDK directory $SDK_DIR not found, skipping copy"
fi

echo ""
echo "=== Build Complete ==="
echo ""
echo "JavaScript builds (wasm-bindgen):"
echo "  - Bundler: pkg/bundler/"
echo "  - Node.js: pkg/nodejs/"
echo "  - Web: pkg/web/"
echo "  - Browser: pkg/browser/"
echo ""
echo "WASI build (C FFI):"
echo "  - WASI: pkg/wasi/"
echo "    - hypen_engine.wasm (WASM module)"
echo "    - hypen.wit (WIT interface definition)"
echo ""
