# Install script for: https://github.com/trailbaseio/trailbase originally
# generated using https://instl.sh. License note at the end.
#
# To use this install script, run the following command:
#
# Linux:
# curl -sSL instl.sh/trailbaseio/trailbase/linux | bash
#
# macOS:
# curl -sSL instl.sh/trailbaseio/trailbase/macos | bash
#
# Windows:
# iwr instl.sh/trailbaseio/trailbase/windows | iex

# --- Sourced from file: ./lib/colors.sh ---

# Foreground Colors
fRed() {
  printf "\e[31m%s\e[0m" "$1"
}

fRedLight() {
  printf "\e[91m%s\e[0m" "$1"
}

fYellow() {
  printf "\e[33m%s\e[0m" "$1"
}

fYellowLight() {
  printf "\e[93m%s\e[0m" "$1"
}

fGreen() {
  printf "\e[32m%s\e[0m" "$1"
}

fGreenLight() {
  printf "\e[92m%s\e[0m" "$1"
}

fBlue() {
  printf "\e[34m%s\e[0m" "$1"
}

fBlueLight() {
  printf "\e[94m%s\e[0m" "$1"
}

fMagenta() {
  printf "\e[35m%s\e[0m" "$1"
}

fMagentaLight() {
  printf "\e[95m%s\e[0m" "$1"
}

fCyan() {
  printf "\e[36m%s\e[0m" "$1"
}

fCyanLight() {
  printf "\e[96m%s\e[0m" "$1"
}

fWhite() {
  printf "\e[37m%s\e[0m" "$1"
}

fBlack() {
  printf "\e[30m%s\e[0m" "$1"
}

fGray() {
  printf "\e[90m%s\e[0m" "$1"
}

fGrayLight() {
  printf "\e[37m%s\e[0m" "$1"
}

# Special Colors
resetColor() {
  printf "\e[0m"
}

# Logging
info() {
  fBlueLight " i " && resetColor && fBlue "$1" && echo
}

warning() {
  fYellowLight " ! " && resetColor && fYellow "$1" && echo
}

error() {
  fRedLight " X " && resetColor && fRed "$1" && echo
  exit 1
}

success() {
  fGreenLight " + " && resetColor && fGreen "$1" && echo
}

verbose() {
  if [ $verbose == true ]; then
    fGrayLight " > " && resetColor && fGray "$1" && echo
  fi
}

# --- End of ./lib/colors.sh ---


# --- Sourced from file: ./lib/map.sh ---

# map_put map_name key value
map_put() {
  alias "${1}$2"="$3"
}

# map_get map_name key
# @return value
map_get() {
  alias "${1}$2" | awk -F"'" '{ print $2; }'
}

# map_keys map_name
# @return map keys
map_keys() {
  alias -p | grep $1 | cut -d'=' -f1 | awk -F"$1" '{print $2; }'
}

# --- End of ./lib/map.sh ---


# Setup variables
if [ "$verbose" = "true" ]; then
  verbose=true
else
  verbose=false
fi

# Pass variables from the go server into the script
verbose "Setting up variables"
owner="trailbaseio"
repo="trailbase"

verbose "Creating temporary directory"
tmpDir="$(mktemp -d)"
verbose "Temporary directory: $tmpDir"

relativeLocation=".local/bin"

binaryLocation="$HOME/$relativeLocation"
verbose "Binary location: $binaryLocation"
mkdir -p "$binaryLocation"

installLocation="$HOME/$relativeLocation/.$repo"
verbose "Install location: $installLocation"

# Remove installLocation directory if it exists
if [ -d "$installLocation" ]; then
	verbose "Removing existing install location"
	rm -rf "$installLocation"
fi
mkdir -p "$installLocation"


# Installation
curlOpts=("-sSL" "--retry" "5" "--retry-delay" "2" "--retry-max-time" "15")
if [ -n "$GH_TOKEN" ]; then
  verbose "Using authentication with GH_TOKEN"
  curlOpts+=("--header" "Authorization: Bearer $GH_TOKEN")
elif [ -n "$GITHUB_TOKEN" ]; then
  verbose "Using authentication with GITHUB_TOKEN"
  curlOpts+=("--header" "Authorization: Bearer $GITHUB_TOKEN")
else
  verbose "No authentication"
fi

# GitHub public API
latestReleaseURL="https://api.github.com/repos/$owner/$repo/releases/latest"
verbose "Getting latest release from GitHub"
getReleaseArgs=("${curlOpts[@]}" "$latestReleaseURL")
verbose "Release curl args: ${getReleaseArgs[*]}"
releaseJSON="$(curl "${getReleaseArgs[@]}")"

tagName="$(echo "$releaseJSON" | grep '"tag_name":' | sed -E 's/.*"([^"]+)".*/\1/')"
info "Found latest release of $repo (version: $tagName)"

# Get list of assets
assets=$(echo "$releaseJSON" | grep "browser_download_url" | sed -E 's/.*"([^"]+)".*/\1/')
verbose "Found assets: $assets"
assetCount="$(echo "$assets" | wc -l | sed -E 's/^[[:space:]]*//')"
info "Found $assetCount assets in '$tagName' - searching for one that fits your system..."

# Get architecture of host
arch="$(uname -m)"
# Convert arch to lowercase
arch="$(echo "$arch" | tr '[:upper:]' '[:lower:]')"
verbose "Host architecture: $arch"

# Set aliases for architectures
amd64=("amd64" "x86_64" "x86-64" "x64")
amd32=("386" "i386" "i686" "x86")
arm=("arm" "armv7" "armv6" "armv8" "armv8l" "armv7l" "armv6l" "armv8l" "armv7l" "armv6l")
aarch64=("aarch64" "arm64")

currentArchAliases=()
# Set the right aliases for current host system
if [ "$arch" == "x86_64" ]; then
  currentArchAliases=("${amd64[@]}")
elif [ "$arch" == "i386" ] || [ "$arch" == "i686" ]; then
  currentArchAliases=("${amd32[@]}")
elif [[ "$arch" = "aarch64" ]]; then
  currentArchAliases=("${aarch64[@]}")
  # Else if starts with "arm"
elif [[ "$arch" =~ ^arm ]]; then
  currentArchAliases=("${arm[@]}")
else
  error "Unsupported architecture: $arch"
fi
verbose "Current architecture aliases: ${currentArchAliases[*]}"

# Get operating system of host
os="$(uname -s)"
# Convert os to lowercase
os="$(echo "$os" | tr '[:upper:]' '[:lower:]')"
verbose "Host operating system: $os"

# Set aliases for operating systems
linux=("linux")
darwin=("darwin" "macos" "osx")

currentOsAliases=()
# If current os is linux, add linux aliases to the curentOsAliases array
if [ "${os}" == "linux" ]; then
  currentOsAliases+=("${linux[@]}")
elif [ "${os}" == "darwin" ]; then
  currentOsAliases+=("${darwin[@]}")
fi
verbose "Current operating system aliases: ${currentOsAliases[*]}"

# Create map of assets and a score
for asset in $assets; do
  score=0

  # Get file name from asset path
  fileName="$(echo "$asset" | awk -F'/' '{ print $NF; }')"
  # Set filename to lowercase
  fileName="$(echo "$fileName" | tr '[:upper:]' '[:lower:]')"

  # Set score to one, if the file name contains the current os
  for osAlias in "${currentOsAliases[@]}"; do
    if [[ "${fileName}" == *"$osAlias"* ]]; then
      score=10
      break
    fi
  done

  # Add two to the score for every alias that matches the current architecture
  for archAlias in "${currentArchAliases[@]}"; do
    if [[ "${fileName}" == *"$archAlias"* ]]; then
      verbose "Adding one to score for asset $fileName because it matches architecture $archAlias"
      score=$((score + 2))
    fi
  done

  # Add one to the score if the file name contains .tar or .tar.gz or .tar.bz2
  if [[ "$fileName" == *".tar" ]] || [[ "$fileName" == *".tar.gz" ]] || [[ "$fileName" == *".tar.bz2" ]]; then
    verbose "Adding one to score for asset $fileName because it is a .tar or .tar.gz or .tar.bz2 file"
    score=$((score + 1))
  fi

  # Add two to the score if the file name contains the repo name
  if [[ "$fileName" == *"$repo"* ]]; then
    verbose "Adding two to score for asset $fileName because it contains the repo name"
    score=$((score + 2))
  fi

  # Add one to the score if the file name is exactly the repo name
  if [[ "$fileName" == "$repo" ]]; then
    verbose "Adding one to score for asset $fileName because it is exactly the repo name"
    score=$((score + 1))
  fi

  # Initialize asset with score
  map_put assets "$fileName" "$score"
done

# Get map entry with highest score
verbose "Finding asset with highest score"
maxScore=0
maxKey=""
for asset in $(map_keys assets); do
  score="$(map_get assets "$asset")"
  if [ $score -gt $maxScore ]; then
    maxScore=$score
    maxKey=$asset
  fi
  verbose "Asset: $asset, score: $score"
done

assetName="$maxKey"

# Check if asset name is still empty
if [ -z "$assetName" ]; then
  error "Could not find any assets that fit your system"
fi

# Get asset URL from release assets
assetURL="$(echo "$assets" | grep -i "$assetName")"

info "Found best match: $assetName"

info "Downloading asset..."
# Download asset
downloadAssetArgs=$curlOpts
downloadAssetArgs+=(-L "$assetURL" -o "$tmpDir/$assetName")
verbose "${downloadAssetArgs[@]}"
curl "${downloadAssetArgs[@]}"

# Unpack asset if it is compressed
if [[ "$assetName" == *".tar" ]]; then
  verbose "Unpacking .tar asset to $tmpDir"
  tar -xf "$tmpDir/$assetName" -C "$tmpDir"
  verbose "Removing packed asset ($tmpDir/$assetName)"
  rm "$tmpDir/$assetName"
elif [[ "$assetName" == *".tar.gz" ]]; then
  verbose "Unpacking .tar.gz asset to $tmpDir"
  tar -xzf "$tmpDir/$assetName" -C "$tmpDir"
  verbose "Removing packed asset ($tmpDir/$assetName)"
  rm "$tmpDir/$assetName"
elif [[ "$assetName" == *".gz" ]]; then
  verbose "Unpacking .gz asset to $tmpDir/$repo"
  gunzip -c "$tmpDir/$assetName" >"$tmpDir/$repo"
  verbose "Removing packed asset ($tmpDir/$assetName)"
  rm "$tmpDir/$assetName"
  verbose "Setting asset name to $repo, because it is a .gz file"
  assetName="$repo"
  verbose "Marking asset as executable"
  chmod +x "$tmpDir/$repo"
elif [[ "$assetName" == *".tar.bz2" ]]; then
  verbose "Unpacking .tar.bz2 asset to $tmpDir"
  tar -xjf "$tmpDir/$assetName" -C "$tmpDir"
  verbose "Removing packed asset"
  rm "$tmpDir/$assetName"
elif [[ "$assetName" == *".zip" ]]; then
  verbose "Unpacking .zip asset to $tmpDir/$repo"
  unzip "$tmpDir/$assetName" -d "$tmpDir" >/dev/null 2>&1
  verbose "Removing packed asset ($tmpDir/$assetName)"
  rm "$tmpDir/$assetName"
else
  verbose "Asset is not a tar or zip file. Skipping unpacking."
fi

# If it was unpacked to a single directory, move the files to the root of the tmpDir
# Also check that there are not other non directory files in the tmpDir
verbose "Checking if asset was unpacked to a single directory"
if [ "$(ls -d "$tmpDir"/* | wc -l)" -eq 1 ] && [ -d "$(ls -d "$tmpDir"/*)" ]; then
  verbose "Asset was unpacked to a single directory"
  verbose "Moving files to root of tmpDir"
  mv "$tmpDir"/*/* "$tmpDir"
else
  verbose "Asset was not unpacked to a single directory"
fi

info "Installing '$repo'"

# Copy files to install location
verbose "Copying files to install location"
verbose "Files in $tmpDir: $(ls "$tmpDir")"
cp -r "$tmpDir"/* "$installLocation"

# Find binary in install location to symlink to it later
verbose "Finding binary in install location"
binary=""
for file in "$installLocation"/*; do
  # Check if the file is a binary file
  verbose "Checking if $file is a binary file"
  if [ -f "$file" ] && [ -x "$file" ]; then
    binary="$file"
    verbose "Found binary: $binary"
    break
  fi
done

# Check if binary is empty
if [ -z "$binary" ]; then
  error "Could not find binary in install location"
fi

# Get name of binary
binaryName="$(basename "$binary")"

# Create symlink to binary
verbose "Creating symlink '$binaryLocation/$binaryName' -> '$binary'"
ln -s -f "$binary" "$binaryLocation/$binaryName"

# Add binaryLocation to PATH, if it is not already in PATH
if ! echo "$PATH" | grep -q "\(\$HOME\|$HOME\)/$relativeLocation"; then
  verbose "Adding $binaryLocation to PATH"

  # Array of common shell configuration files
  config_files=("$HOME/.bashrc" "$HOME/.bash_profile" "$HOME/.zshrc" "$HOME/.profile")
  for config in "${config_files[@]}"; do
    # Check if the file exists
    if [ ! -f "$config" ]; then
      verbose "$config does not exist. Skipping append."
      continue
    fi

    # Check if binaryLocation is already in the file
    if grep -q -s "PATH=.*\(\$HOME\|$HOME\)/$relativeLocation" "$config"; then
      verbose "$binaryLocation is already in $config"
      continue
    fi

    if [ ! -w "$config" ]; then
      warning "Cannot append PATH: $config is write-protected. Consider adding 'export PATH=\$PATH:$binaryLocation' manually."
      continue
    fi

    verbose "Appending \$HOME/$relativeLocation to $config"
    echo "" >>"$config"
    echo "export PATH=\$HOME/$relativeLocation:\$PATH" >>"$config"
  done

  info "You may have to restart your terminal session for the changes to take effect"
else
  verbose "$binaryLocation is already in PATH"
fi

info "Cleaning up download directory"
rm -rf "$tmpDir"

# Test if binary exists
if [ ! -f "$binary" ]; then
  error "Binary does not exist in installation location"
fi

echo
success "You can now run '$binaryName' in your terminal!"


##################################################################################
# MIT License                                                                    #
#                                                                                #
# Copyright (c) 2022 Marvin Wendt (Instl | https://instl.sh)                     #
#                                                                                #
# Permission is hereby granted, free of charge, to any person obtaining a copy   #
# of this software and associated documentation files (the "Software"), to deal  #
# in the Software without restriction, including without limitation the rights   #
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell      #
# copies of the Software, and to permit persons to whom the Software is          #
# furnished to do so, subject to the following conditions:                       #
#                                                                                #
# The above copyright notice and this permission notice shall be included in all #
# copies or substantial portions of the Software.                                #
#                                                                                #
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR     #
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,       #
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE    #
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER         #
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,  #
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE  #
# SOFTWARE.                                                                      #
##################################################################################

# --------------------------------- Metadata ----------------------------------- #

# Script generated for https://github.com/trailbaseio/trailbase
# Script generated at 2025-08-06 13:54:21.072252385 +0000 UTC m=+12582048.854684577
# Script generated for version "latest"
# Script generated with instl version "dev"
