#!/bin/bash
# Copyright 2026, Jiri Eischmann <jiri@eischmann.cz> and the meshy contributors
# SPDX-License-Identifier: GPL-3.0-or-later

# Create Homebrew-optimized Meshy.app bundle
# Uses dependencies from Homebrew instead of bundling them
# Result: Small ~15-20 MB bundle that requires gtk4/libadwaita from brew

set -e

# Colors
GREEN='\033[0;32m'
BLUE='\033[0;34m'
YELLOW='\033[1;33m'
RED='\033[0;31m'
NC='\033[0m'

info() { echo -e "${GREEN}==>${NC} $1"; }
warn() { echo -e "${YELLOW}Warning:${NC} $1"; }
error() { echo -e "${RED}Error:${NC} $1"; exit 1; }

[[ "$(uname)" == "Darwin" ]] || error "Must run on macOS"

# Parse command line options
SIGN_IDENTITY=""
CREATE_DMG=false
NOTARIZE=false
KEYCHAIN_PROFILE=""

while [[ $# -gt 0 ]]; do
    case "$1" in
        --sign)
            SIGN_IDENTITY="$2"
            shift 2
            ;;
        --dmg)
            CREATE_DMG=true
            shift
            ;;
        --notarize)
            NOTARIZE=true
            KEYCHAIN_PROFILE="$2"
            shift 2
            ;;
        --help|-h)
            echo "Usage: $0 [OPTIONS]"
            echo ""
            echo "Options:"
            echo "  --sign IDENTITY         Sign the bundle with specified identity"
            echo "                          (default: unsigned)"
            echo "  --dmg                   Create DMG installer after building"
            echo "  --notarize PROFILE      Notarize DMG using keychain profile"
            echo "                          (requires --dmg and --sign)"
            echo "  --help, -h              Show this help message"
            echo ""
            echo "Examples:"
            echo "  $0                                              # Build unsigned bundle"
            echo "  $0 --dmg                                        # Build and create unsigned DMG"
            echo "  $0 --sign \"Developer ID\"                       # Build and sign"
            echo "  $0 --sign \"Developer ID\" --dmg                 # Build, sign, and create DMG"
            echo "  $0 --sign \"Developer ID\" --dmg --notarize prof # Build, sign, create DMG, and notarize"
            exit 0
            ;;
        *)
            error "Unknown option: $1 (use --help for usage)"
            ;;
    esac
done

# Validate options
if [[ "$NOTARIZE" == "true" ]]; then
    [[ "$CREATE_DMG" == "true" ]] || error "--notarize requires --dmg"
    [[ -n "$SIGN_IDENTITY" ]] || error "--notarize requires --sign"
    [[ -n "$KEYCHAIN_PROFILE" ]] || error "--notarize requires a keychain profile name"
fi

# Get version using same logic as meson.build (matching Linux versioning)
# If on a tag, use tag; otherwise use date version (YY.MM.DD format)
if git describe --tags --exact-match >/dev/null 2>&1; then
    # On a tag - use tag version (e.g., 26.06)
    VERSION=$(git describe --tags --exact-match 2>/dev/null)
else
    # Not on a tag - use date version matching meson's date_version (YY.MM.DD)
    VERSION=$(python3 -c 'import time; print(time.strftime("%y.%m.%d", time.gmtime()))')
fi

# Verify Homebrew dependencies
info "Checking Homebrew dependencies"
brew list gtk4 >/dev/null 2>&1 || error "gtk4 not installed. Run: brew install gtk4"
brew list libadwaita >/dev/null 2>&1 || error "libadwaita not installed. Run: brew install libadwaita"
brew list python@3.14 >/dev/null 2>&1 || error "python@3.14 not installed. Run: brew install python@3.14"

# Configuration
APP_NAME="Meshy"
DIST_DIR="dist-homebrew"
APP_DIR="$DIST_DIR/${APP_NAME}.app"
CONTENTS_DIR="$APP_DIR/Contents"
MACOS_DIR="$CONTENTS_DIR/MacOS"
RESOURCES_DIR="$CONTENTS_DIR/Resources"

info "Building Homebrew-optimized ${APP_NAME}.app bundle (version ${VERSION})"

# Step 1: Build base app
info "Step 1/6: Building base application"
bash build-aux/macos/build-app-bundle.sh

# Move to homebrew dist directory
rm -rf "$DIST_DIR"
mkdir -p "$DIST_DIR"
cp -R dist/Meshy.app "$APP_DIR"

info "Step 2/6: Installing Python packages (minimal - no framework bundling)"
mkdir -p "$RESOURCES_DIR/lib/python-packages"

# Use Homebrew Python to install packages
# Force ARM64 architecture to avoid Rosetta requirement
export ARCHFLAGS="-arch arm64"
export _PYTHON_HOST_PLATFORM="macosx-14.0-arm64"
arch -arm64 /opt/homebrew/bin/python3.14 -m pip install \
    --target="$RESOURCES_DIR/lib/python-packages" \
    pycryptodome \
    pyserial \
    segno \
    pyobjc-framework-Cocoa \
    pyobjc-framework-CoreBluetooth \
    pyobjc-framework-CoreLocation \
    pyobjc-framework-AVFoundation \
    pyobjc-framework-Vision \
    pyobjc-framework-UserNotifications \
    pyobjc-framework-libdispatch \
    pygobject

# Strip x86_64 architecture from universal binaries to avoid Rosetta requirement
info "Stripping x86_64 from universal binaries..."
find "$RESOURCES_DIR/lib/python-packages" -type f \( -name "*.so" -o -name "*.dylib" \) | while read -r binary; do
    if file "$binary" | grep -q "universal binary"; then
        lipo "$binary" -thin arm64 -output "$binary.arm64" 2>/dev/null && mv "$binary.arm64" "$binary" || true
    fi
done

info "Step 3/6: Compiling native launcher (so permissions show 'Meshy' not 'python 3.14')"

# Compile C launcher - this makes macOS show "Meshy" instead of "python 3.14" in permission dialogs
cc -O2 -arch arm64 -o "$MACOS_DIR/meshy" build-aux/macos/launcher.c

info "Step 4/6: Creating Python entry point"

cat > "$RESOURCES_DIR/lib/python/meshy/__main__.py" << 'PYTHON_EOF'
#!/usr/bin/env python3
import os
import sys
import gettext

# Set up package data directory
pkgdatadir = os.environ.get('MESHY_PKGDATADIR', '/opt/homebrew/share/meshy')
localedir = os.path.join(os.path.dirname(__file__), '..', '..', '..', 'share', 'locale')

# Initialize gettext for translations
gettext.install('meshy', localedir)

# Initialize meshy package globals
import meshy as _meshy_pkg
_meshy_pkg.pkgdatadir = pkgdatadir
_meshy_pkg.QR_SCANNER_ENABLED = True  # Native AVFoundation + Vision implementation
_meshy_pkg.SHORTCUTS_DIALOG_ENABLED = True

# Verify GObject Introspection can load macOS backend
import gi
gi.require_version("Gtk", "4.0")
try:
    gi.require_version("GdkMacos", "4.0")
except ValueError as e:
    print(f"✗ CRITICAL: Cannot load GdkMacos backend: {e}", file=sys.stderr)
    print(f"  Ensure GTK4 is installed: brew install gtk4", file=sys.stderr)
    sys.exit(1)

# Import GTK and verify initialization
from gi.repository import Gtk, Gio
print(f"✓ GTK {Gtk.get_major_version()}.{Gtk.get_minor_version()}.{Gtk.get_micro_version()} (Homebrew)", file=sys.stderr)

# Load GResource file
gresource_path = os.path.join(os.path.dirname(__file__), '..', '..', '..', 'share', 'meshy', 'meshy.gresource')
if os.path.exists(gresource_path):
    resource = Gio.Resource.load(gresource_path)
    Gio.resources_register(resource)
    print(f"✓ Loaded GResource from {gresource_path}", file=sys.stderr)
else:
    print(f"✗ WARNING: GResource not found at {gresource_path}", file=sys.stderr)

from meshy.main import main

if __name__ == '__main__':
    sys.exit(main('$VERSION'))
PYTHON_EOF

STEP_NUM=5
if [[ "$NOTARIZE" == "true" ]]; then
    TOTAL_STEPS=6
else
    TOTAL_STEPS=5
fi

info "Step $STEP_NUM/$TOTAL_STEPS: Code signing bundle"

if [[ -n "$SIGN_IDENTITY" ]]; then
    info "Signing with identity: $SIGN_IDENTITY"

    # Create entitlements file for hardened runtime
    ENTITLEMENTS_FILE="$DIST_DIR/entitlements.plist"
    cat > "$ENTITLEMENTS_FILE" << 'EOF'
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
    <key>com.apple.security.cs.allow-unsigned-executable-memory</key>
    <true/>
    <key>com.apple.security.cs.disable-library-validation</key>
    <true/>
</dict>
</plist>
EOF

    # Sign all .so files and dylibs in Python packages (required for notarization)
    info "Signing Python native extensions..."
    find "$RESOURCES_DIR/lib/python-packages" -type f \( -name "*.so" -o -name "*.dylib" \) 2>/dev/null | while read -r lib; do
        codesign --force --sign "$SIGN_IDENTITY" --timestamp --options runtime \
            --entitlements "$ENTITLEMENTS_FILE" "$lib" 2>/dev/null || true
    done

    # Sign the launcher
    codesign --force --sign "$SIGN_IDENTITY" --timestamp --options runtime \
        --entitlements "$ENTITLEMENTS_FILE" "$MACOS_DIR/meshy" || error "Failed to sign launcher"

    # Sign the app bundle
    codesign --force --sign "$SIGN_IDENTITY" --timestamp --options runtime \
        --entitlements "$ENTITLEMENTS_FILE" "$APP_DIR" || error "Failed to sign app bundle"

    info "✓ Bundle signed successfully"
else
    info "Skipping code signing (use --sign to enable)"
fi

# Calculate bundle size
BUNDLE_SIZE=$(du -sh "$APP_DIR" | awk '{print $1}')

info ""
info "✅ Homebrew-optimized bundle created successfully!"
info ""
info "Bundle size: $BUNDLE_SIZE"
info "Location: $APP_DIR"
info ""
info "Dependencies (from Homebrew):"
info "  • gtk4 (brew install gtk4)"
info "  • libadwaita (brew install libadwaita)"
info "  • python@3.14 (brew install python@3.14)"
info ""
info "To test:"
info "  open $APP_DIR"
info ""

# Create DMG if requested
if [[ "$CREATE_DMG" == "true" ]]; then
    info "Creating DMG installer..."
    DMG_NAME="Meshy-${VERSION}.dmg"
    DMG_PATH="$DIST_DIR/$DMG_NAME"

    hdiutil create -volname "Meshy ${VERSION}" -srcfolder "$APP_DIR" -ov -format UDZO "$DMG_PATH"

    # Sign DMG if identity provided
    if [[ -n "$SIGN_IDENTITY" ]]; then
        info "Signing DMG..."
        codesign --force --sign "$SIGN_IDENTITY" --timestamp "$DMG_PATH" || warn "Failed to sign DMG"
    fi

    DMG_SIZE=$(du -sh "$DMG_PATH" | awk '{print $1}')
    info ""
    info "✅ DMG created: $DMG_PATH ($DMG_SIZE)"
    info ""

    # Notarize DMG if requested
    if [[ "$NOTARIZE" == "true" ]]; then
        info "Step 6/6: Notarizing DMG..."
        info "Submitting $DMG_NAME to Apple notary service..."

        SUBMIT_OUTPUT=$(xcrun notarytool submit "$DMG_PATH" --keychain-profile "$KEYCHAIN_PROFILE" --wait 2>&1)

        if echo "$SUBMIT_OUTPUT" | grep -q "status: Accepted"; then
            info "✓ Notarization accepted"
            info "Stapling notarization ticket..."
            xcrun stapler staple "$DMG_PATH"
            info ""
            info "✅ DMG notarized successfully!"
            info ""
        else
            error "Notarization failed. Output:\n$SUBMIT_OUTPUT"
        fi
    fi

    info "Distribution naming convention:"
    info "  Stable release:   Meshy-26.06.dmg (from tag)"
    info "  Unstable/Nightly: Meshy-26.06.19.dmg (date version)"
    info ""
else
    info "To create DMG for distribution:"
    info "  $0 --dmg"
    info "  Or manually: hdiutil create -volname 'Meshy ${VERSION}' -srcfolder $APP_DIR -ov -format UDZO $DIST_DIR/Meshy-${VERSION}.dmg"
    info ""
fi
