#!/bin/bash
#
# MyTechie RustDesk Auto-Installer (macOS)
# Version: 2.4.0
# RustDesk: 1.4.9
#

set -euo pipefail

installer_version="2.4.0"
rustdesk_version="1.4.9"
support_url="https://mytechie.com.au/remote/"
rustdesk_cfg="0nI9MnVR9Uc2I1dGVWNQRUZn1UU3Q0cQ1UV6NVUoljQkdUTWV0YZVWdhlnYShjI6ISeltmIsIyNxETMyoTdh5SbvNmLllGajVGd51mLlR3btVmciojI5FGblJnIsIiNxETMyoTdh5SbvNmLllGajVGd51mLlR3btVmciojI0N3boJye"
verify_only=0
pkg_mode="${MYTECHIE_PKG_MODE:-0}"
workdir=""
mountpoint=""
failure_code=""

if [[ "${1:-}" == "--verify-only" ]]; then
    verify_only=1
elif [[ $# -gt 0 ]]; then
    echo "Unknown option: $1"
    exit 2
fi

step() {
    printf '[%s/5] %s\n' "$1" "$2"
}

fail() {
    failure_code="$1"
    printf '\nSetup failed (%s).\n%s\n' "$1" "$2" >&2
    printf 'Leave this window open and contact your MyTechie technician: %s\n' "$support_url" >&2
    exit 1
}

cleanup() {
    if [[ -n "$mountpoint" ]]; then
        hdiutil detach "$mountpoint" -quiet >/dev/null 2>&1 || true
    fi
    if [[ -n "$workdir" ]]; then
        rm -rf "$workdir"
    fi
}

on_exit() {
    status=$?
    cleanup
    if [[ $status -ne 0 && -z "$failure_code" ]]; then
        printf '\nSetup stopped unexpectedly. Leave this window open and contact your MyTechie technician: %s\n' "$support_url" >&2
    fi
    if [[ "$pkg_mode" == "1" ]]; then
        package_script="$0"
        package_dir=$(dirname "$package_script")
        rm -f "$package_script" 2>/dev/null || true
        rmdir "$package_dir" 2>/dev/null || true
        if [[ -t 0 ]]; then
            printf '\nPress Return to close this window.'
            read -r _ || true
        fi
    fi
    exit "$status"
}
trap on_exit EXIT

printf '\n=== MyTechie Remote Support Installer v%s (macOS) ===\n\n' "$installer_version"

if [[ "$pkg_mode" == "1" && $EUID -ne 0 ]]; then
    exec sudo env MYTECHIE_PKG_MODE=1 /bin/bash "$0"
fi

if [[ $verify_only -eq 0 && $EUID -ne 0 ]]; then
    fail "MAC-ELEVATION" "Administrator access is required. Run: curl -fsSL https://mytechie.com.au/remote/macos.sh | sudo bash"
fi

case "$(uname -m)" in
    arm64)
        asset="rustdesk-${rustdesk_version}-aarch64.dmg"
        expected_sha256="f7935597b247d42c8f2a2ed71176a9f5868018cd9e1a33b8096418a668c8caf0"
        ;;
    x86_64)
        asset="rustdesk-${rustdesk_version}-x86_64.dmg"
        expected_sha256="fa1129a0635019f9c5841937942cc2b08be028a192f47c009edde7e53812904e"
        ;;
    *)
        fail "MAC-ARCH" "Unsupported macOS architecture: $(uname -m)"
        ;;
esac

download_and_verify() {
    workdir=$(mktemp -d)
    chmod 700 "$workdir"
    dmg_path="$workdir/$asset"
    url="https://github.com/rustdesk/rustdesk/releases/download/${rustdesk_version}/${asset}"

    curl --fail --location --silent --show-error \
        --retry 3 --retry-delay 2 --connect-timeout 15 \
        --proto '=https' --tlsv1.2 \
        -H "User-Agent: MyTechie-RustDesk-Installer/${installer_version}" \
        "$url" -o "$dmg_path" ||
        fail "MAC-DOWNLOAD" "RustDesk could not be downloaded after three attempts."

    actual_sha256=$(shasum -a 256 "$dmg_path" | awk '{print $1}')
    if [[ "$actual_sha256" != "$expected_sha256" ]]; then
        fail "MAC-INTEGRITY" "The RustDesk download did not match the approved SHA-256 digest."
    fi

    printf 'Verified RustDesk %s (%s).\n' "$rustdesk_version" "$asset"
}

if [[ $verify_only -eq 1 ]]; then
    step 1 "Checking the approved RustDesk package"
    download_and_verify
    printf 'Verification complete. No software was installed.\n'
    exit 0
fi

step 1 "Checking this Mac"
printf 'Architecture: %s\n' "$(uname -m)"

app="/Applications/RustDesk.app"
binary="$app/Contents/MacOS/RustDesk"

if [[ -x "$binary" ]]; then
    installed_version=$(/usr/libexec/PlistBuddy -c 'Print :CFBundleShortVersionString' "$app/Contents/Info.plist" 2>/dev/null || true)
    printf 'RustDesk %s is already installed. The existing app will be configured.\n' "${installed_version:-unknown}"
else
    step 2 "Downloading and verifying RustDesk $rustdesk_version"
    download_and_verify

    mountpoint="$workdir/mount"
    mkdir -p "$mountpoint"
    hdiutil attach "$dmg_path" -nobrowse -readonly -mountpoint "$mountpoint" -quiet ||
        fail "MAC-MOUNT" "The verified RustDesk disk image could not be mounted."

    candidate="$mountpoint/RustDesk.app"
    [[ -d "$candidate" ]] || fail "MAC-MOUNT" "RustDesk.app was not present in the verified disk image."

    codesign --verify --deep --strict "$candidate" >/dev/null 2>&1 ||
        fail "MAC-SIGNATURE" "The RustDesk application signature was invalid."
    spctl -a -t exec "$candidate" >/dev/null 2>&1 ||
        fail "MAC-NOTARIZATION" "macOS did not accept the RustDesk notarization."

    printf 'Installing RustDesk...\n'
    rm -rf "$app"
    ditto "$candidate" "$app"
fi

[[ -x "$binary" ]] || fail "MAC-INSTALL" "RustDesk was not found in /Applications after installation."

step 3 "Configuring the MyTechie relay and support password"
support_password=$(LC_ALL=C dd if=/dev/urandom bs=48 count=1 2>/dev/null |
    base64 | tr -dc 'abcdefghijkmnopqrstuvwxyzABCDEFGHJKLMNPQRSTUVWXYZ23456789' |
    cut -c1-16)
"$binary" --config "$rustdesk_cfg" >/dev/null ||
    fail "MAC-CONFIG" "RustDesk rejected the MyTechie server configuration."
"$binary" --password "$support_password" >/dev/null ||
    fail "MAC-PASSWORD" "RustDesk could not set the support access password."

step 4 "Opening RustDesk"
launch_user="${SUDO_USER:-$(stat -f '%Su' /dev/console)}"
if [[ -n "$launch_user" && "$launch_user" != "root" && "$launch_user" != "loginwindow" ]]; then
    sudo -u "$launch_user" open -a RustDesk ||
        fail "MAC-LAUNCH" "RustDesk was installed but could not be opened in the signed-in desktop session."
else
    open -a RustDesk ||
        fail "MAC-LAUNCH" "RustDesk was installed but could not be opened."
fi

step 5 "Waiting for this device's RustDesk ID"
rustdesk_id=""
for attempt in $(seq 1 15); do
    rustdesk_id=$("$binary" --get-id 2>/dev/null | tr -cd '0-9' || true)
    if [[ ${#rustdesk_id} -ge 6 ]]; then
        break
    fi
    printf 'Waiting for registration... (%s/15)\n' "$attempt"
    sleep 2
done

if [[ ${#rustdesk_id} -lt 6 ]]; then
    fail "MAC-ID" "RustDesk is installed, but its ID is not ready. Open RustDesk in Applications and tell your technician the ID shown there."
fi

printf '\n=========================================\n'
printf ' MyTechie Remote Support Setup Complete\n'
printf '=========================================\n\n'
printf 'RustDesk ID:      %s\n' "$rustdesk_id"
printf 'Access password:  %s\n\n' "$support_password"
printf 'Share these details only with your MyTechie technician.\n'
printf 'This password remains active until it is changed, the installer is rerun, or RustDesk is removed.\n\n'
printf 'macOS may ask for Accessibility and Screen Recording permission. Allow both so your technician can see and control the screen.\n'
printf 'You may now close this Terminal window.\n\n'
