#!/bin/bash
# Install the Particle Command Line Interface (CLI)
#
# This installs a binary wrapper to the home directory.
#
# That binary wrapper will download its own version of Node to ~/.particle
#
# It will also download the particle-cli npm module which contains the
# actual Particle CLI logic to ~/.particle/node_modules.
# When a new version of the particle-cli is released, the binary wrapper
# will update to the latest version in the background.
#
# Run CHANNEL=beta ./install-cli to use the beta version

CHANNEL=${CHANNEL:-master}
BINARY="particle"
DEST_PATH="$HOME/bin"
DEST="$DEST_PATH/$BINARY"
MANIFEST_URL="https://binaries.particle.io/cli/${CHANNEL}/manifest.json"
SHELL_CONFIG="$HOME/.bash_profile"

echo
echo 'PARTICLE CLI SETUP...'
echo

# Compute OS and architecture
UNAME=$(uname -s)
case $UNAME in
    Linux)
        OS="linux"
        ;;
    Darwin)
        OS="darwin"
        ;;
    *)
        echo "Don't know how to install the Particle CLI on $UNAME"
        exit 1
        ;;
esac

PROCESSOR=$(uname -m)
case $PROCESSOR in
    x86_64)
        ARCH="amd64"
        ;;
    i686)
        ARCH="386"
        ;;
    arm*)
        ARCH="arm"
        ;;
    *)
        echo "Don't know how to install the Particle CLI for $PROCESSOR"
        exit 1
        ;;
esac

# warn and exit if we're running on an Appple M1 processor
if [ "$OS" = "darwin" ] && [ "$ARCH" == "arm" ]; then
    echo "Apple M1 processor detected!"
    echo "Particle CLI must be run under Rosetta"
    echo "To enable Rosetta, see:"
    echo "https://community.particle.io/t/apple-m1-support/59403/3"
    exit 1
fi

# setup for legacy macOS bash
if [ -e "$HOME/.profile" ] && [ "${OS}" == "darwin" ]; then
   SHELL_CONFIG="$HOME/.profile"
fi

# setup for zsh if that's the prefered shell
if [ -n "$($SHELL -c 'echo $ZSH_VERSION')" ]; then
   SHELL_CONFIG="$HOME/.zprofile"
fi

function program_exists {
    hash "$1" 2> /dev/null
}

if program_exists "python3"; then
   PYTHON=python3
elif program_exists "python2"; then
   PYTHON=python2
elif program_exists "python"; then
   PYTHON=python
else
   echo "python is required to run this installer"
   exit 1
fi

# Download JSON manifest with latest CLI binary
echo ":::: Installing the Particle CLI for $OS to \"$DEST\""

BINARY_URL=$(curl -s $MANIFEST_URL | $PYTHON -c "import sys, json; print(json.load(sys.stdin)['builds']['$OS']['$ARCH']['url'])")
BINARY_SHA256=$(curl -s $MANIFEST_URL | $PYTHON -c "import sys, json; print(json.load(sys.stdin)['builds']['$OS']['$ARCH']['sha256'])")

# Download and validate binary
mkdir -p "$DEST_PATH"
TMP_FILE=$(mktemp)

curl -s "$BINARY_URL.gz" | gunzip > "$TMP_FILE"

echo "$BINARY_SHA256  $TMP_FILE" | shasum a 256 -c > /dev/null 2>&1
if [ $? -eq 1 ]; then
   echo ':::: Checksum check failed! Aborting installation'
   exit 1
fi

mv -f "$TMP_FILE" "$DEST"
chmod +x "$DEST"

# Run binary for the first time to make it install Node and the
# particle-cli npm module
"$DEST" > /dev/null 2>&1

echo ':::: Done!'
echo ':::: Installing dependencies'

# Install dependencies
function install_program {
    prog="$1"

    if ! program_exists "$prog"; then
        if [ "$OS" = "linux" ]; then
            if program_exists "apt-get"; then
                echo ":::: Installing dependency $prog"
                sudo apt-get install -y "$prog"
                return
            fi
        else
            if program_exists "brew"; then
                echo ":::: Installing dependency $prog"
                brew install "$prog"
                return
            fi
        fi
        echo ":::: The Particle CLI uses $prog. Install it for your OS"
    fi
}

install_program "dfu-util"
install_program "openssl"

echo ':::: Done!'


# Add ~/bin to the path
function file_contains {
    grep "$2" "$1" 1>/dev/null 2>&1
}

if ! file_contains "$SHELL_CONFIG" "\$HOME/bin"; then
    cat >> "$SHELL_CONFIG" <<EOL

# added by Particle CLI
# add home bin directory to PATH if it exists
if [ -d "\$HOME/bin" ] ; then
    PATH="\$HOME/bin:\$PATH"
fi
EOL
fi

echo ":::: Success!"
echo ":::: The Particle CLI has been installed to: \"$DEST_PATH\""
echo ":::: Your \"$SHELL_CONFIG\" file has been updated to properly set \$PATH"
echo ":::: If you previously installed the CLI with npm, run \"npm uninstall -g particle-cli\""
echo
echo '************************************************************************'
echo '** YOU MUST CLOSE AND REOPEN YOUR TERMINAL BEFORE CHANGES TAKE EFFECT **'
echo '************************************************************************'
echo