#!/usr/bin/env bash
# BulkaAI Installer - Universal Installation Script
# Usage: curl -fsSL https://files.bulka.ai/public/latest/install.sh | bash
#
# Environment variables:
#   BULKAAI_INSTALL_DIR - Override default installation directory
#   BULKAAI_VERSION     - Install specific version (default: latest)
#
# This script downloads and installs the BulkaAI CLI tool for Linux and macOS.

set -eu

# ============================================================================
# Configuration
# ============================================================================

BASE_URL="${BULKAAI_BASE_URL:-https://files.bulka.ai/public}"
VERSION="${BULKAAI_VERSION:-latest}"
BINARY_NAME="bulkaai"
DEFAULT_INSTALL_DIR="/usr/local/bin"

# ============================================================================
# Output Helpers
# ============================================================================

# Check if stdout is a terminal
is_tty() {
    [ -t 1 ]
}

# Color codes (only if TTY)
if is_tty; then
    ESC=$(printf '\033')
    RED="${ESC}[0;31m"
    GREEN="${ESC}[0;32m"
    YELLOW="${ESC}[0;33m"
    BLUE="${ESC}[0;34m"
    BOLD="${ESC}[1m"
    RESET="${ESC}[0m"
else
    RED=''
    GREEN=''
    YELLOW=''
    BLUE=''
    BOLD=''
    RESET=''
fi

say() {
    printf '%s==>%s %s\n' "$GREEN" "$RESET" "$1"
}

say_verbose() {
    printf '%s   %s%s\n' "$BLUE" "$1" "$RESET"
}

warn() {
    printf '%sWarning:%s %s\n' "$YELLOW" "$RESET" "$1" >&2
}

err() {
    printf '%sError:%s %s\n' "$RED" "$RESET" "$1" >&2
    exit 1
}

# ============================================================================
# Utility Functions
# ============================================================================

# Check if a command exists
check_cmd() {
    command -v "$1" >/dev/null 2>&1
}

# Require a command to exist
need_cmd() {
    if ! check_cmd "$1"; then
        err "Required command not found: $1"
    fi
}

# ============================================================================
# Platform Detection
# ============================================================================

detect_os() {
    os="$(uname -s)"
    case "$os" in
        Linux*)  echo "linux" ;;
        Darwin*) echo "darwin" ;;
        MINGW*|MSYS*|CYGWIN*)
            err "Windows detected. Please use the PowerShell installer instead:
    irm https://files.bulka.ai/public/latest/install.ps1 | iex"
            ;;
        *)
            err "Unsupported operating system: $os
Supported: Linux, macOS"
            ;;
    esac
}

# Detect the CPU architecture for the INSTALLER BINARY download.
#
# macOS gotcha: under Rosetta 2 (x86_64 shell/terminal on an Apple-silicon
# Mac) `uname -m` reports x86_64, which previously delivered the amd64
# binary to arm64 Macs. `sysctl -n hw.optional.arm64` reports 1 on Apple
# silicon regardless of translation (the key does not exist on Intel Macs),
# so it wins over uname.
#
# NOTE: this is the BINARY arch only. The Docker IMAGE arch is a separate
# dimension chosen by the installer from the Docker daemon's architecture
# (bulka-app is published linux/amd64-only today and runs under Rosetta/qemu
# on Apple silicon — the POC-proven setup). Do not conflate the two.
detect_arch() {
    arch="$(uname -m)"

    if [ "$(uname -s)" = "Darwin" ]; then
        if [ "$(sysctl -n hw.optional.arm64 2>/dev/null || echo 0)" = "1" ]; then
            arch="arm64"
        fi
    fi

    case "$arch" in
        x86_64|amd64)
            echo "amd64"
            ;;
        arm64|aarch64)
            echo "arm64"
            ;;
        *)
            err "Unsupported architecture: $arch
Supported: x86_64 (amd64), arm64 (aarch64)"
            ;;
    esac
}

# ============================================================================
# Download Functions
# ============================================================================

download() {
    url="$1"
    output="$2"

    if check_cmd curl; then
        curl --proto '=https' --tlsv1.2 -fsSL "$url" -o "$output"
    elif check_cmd wget; then
        wget --https-only -q "$url" -O "$output"
    else
        err "Neither curl nor wget found. Please install one of them."
    fi
}

# ============================================================================
# Checksum Verification
# ============================================================================

compute_sha256() {
    file="$1"
    if check_cmd sha256sum; then
        sha256sum "$file" | cut -d' ' -f1
    elif check_cmd shasum; then
        shasum -a 256 "$file" | cut -d' ' -f1
    else
        # No checksum tool available
        echo ""
    fi
}

verify_checksum() {
    file="$1"
    expected="$2"

    if [ -z "$expected" ]; then
        warn "Could not verify checksum (checksum tool not available)"
        return 0
    fi

    actual=$(compute_sha256 "$file")

    if [ -z "$actual" ]; then
        warn "Could not verify checksum (checksum tool not available)"
        return 0
    fi

    if [ "$actual" != "$expected" ]; then
        err "Checksum verification failed!
Expected: $expected
Got:      $actual

This could indicate a corrupted download or tampering.
Please try again or report this issue."
    fi
}

# ============================================================================
# Installation
# ============================================================================

install_binary() {
    src="$1"
    dest="$2"
    dest_dir="$(dirname "$dest")"

    # Check if we can write to the destination
    if [ -w "$dest_dir" ]; then
        mv "$src" "$dest"
        chmod +x "$dest"
    else
        say "Elevated privileges required to install to $dest_dir"
        if ! check_cmd sudo; then
            err "Cannot write to $dest_dir and sudo is not available.
Please run as root or set BULKAAI_INSTALL_DIR to a writable directory."
        fi
        sudo mv "$src" "$dest"
        sudo chmod +x "$dest"
    fi
}

# ============================================================================
# Main Installation Logic
# ============================================================================

main() {
    tmp_dir=""

    # Set up cleanup trap early (tmp_dir initialized to empty, safe with set -u)
    trap 'rm -rf "${tmp_dir}"' EXIT

    say "Detecting platform..."
    os=$(detect_os)
    arch=$(detect_arch)

    # Validate platform/arch combination
    if [ "$os" = "linux" ] && [ "$arch" != "amd64" ]; then
        err "Linux builds are only available for amd64 architecture.
Your architecture: $arch"
    fi

    say_verbose "Operating system: $os"
    say_verbose "Architecture: $arch"

    # Determine installation directory
    install_dir="${BULKAAI_INSTALL_DIR:-$DEFAULT_INSTALL_DIR}"

    # Build URLs
    binary_name="${BINARY_NAME}-${os}-${arch}"
    binary_url="${BASE_URL}/${VERSION}/${binary_name}"
    checksums_url="${BASE_URL}/${VERSION}/SHA256SUMS"

    say "Downloading BulkaAI installer binary ($VERSION)..."
    say_verbose "URL: $binary_url"

    # Create temporary directory
    tmp_dir=$(mktemp -d)

    # Download binary
    if ! download "$binary_url" "$tmp_dir/$BINARY_NAME"; then
        err "Failed to download installer binary from $binary_url
Please check your internet connection and try again."
    fi

    # Download and verify checksum
    say "Verifying checksum..."
    if download "$checksums_url" "$tmp_dir/SHA256SUMS" 2>/dev/null; then
        expected_checksum=$(grep "$binary_name" "$tmp_dir/SHA256SUMS" 2>/dev/null | cut -d' ' -f1 || echo "")
        if [ -n "$expected_checksum" ]; then
            verify_checksum "$tmp_dir/$BINARY_NAME" "$expected_checksum"
            say_verbose "Checksum verified successfully"
        else
            warn "Checksum not found in SHA256SUMS file"
        fi
    else
        warn "Could not download checksums file, skipping verification"
    fi

    # Install binary
    say "Installing to ${install_dir}/${BINARY_NAME}..."

    # Create install directory if it doesn't exist
    if [ ! -d "$install_dir" ]; then
        if [ -w "$(dirname "$install_dir")" ]; then
            mkdir -p "$install_dir"
        else
            say "Creating $install_dir (requires elevated privileges)"
            sudo mkdir -p "$install_dir"
        fi
    fi

    install_binary "$tmp_dir/$BINARY_NAME" "${install_dir}/${BINARY_NAME}"

    # Verify installation
    if [ -x "${install_dir}/${BINARY_NAME}" ]; then
        say "BulkaAI installed successfully!"
        echo ""
        # Show exactly what landed (version + build stamp) so a stale binary
        # is immediately visible — same-version republishes differ by Built:.
        "${install_dir}/${BINARY_NAME}" version 2>/dev/null | sed 's/^/  /' || true
        echo ""
        printf '%sNext steps:%s\n' "$BOLD" "$RESET"

        # Check if install_dir is in PATH
        case ":$PATH:" in
            *":${install_dir}:"*)
                echo "  Run 'bulkaai --help' to get started"
                echo "  Run 'bulkaai install' to set up BulkaAI"
                ;;
            *)
                echo "  Add ${install_dir} to your PATH:"
                echo ""
                echo "    export PATH=\"\$PATH:${install_dir}\""
                echo ""
                echo "  Then run 'bulkaai --help' to get started"
                ;;
        esac
        echo ""
    else
        err "Installation verification failed. Binary not executable."
    fi
}

# ============================================================================
# Entry Point
# ============================================================================
# All code is wrapped in functions to prevent partial execution issues
# when piping from curl. The main() function is called at the very end.
# ============================================================================

main "$@"
