#!/bin/bash
# dependencies, jq
# if you have run into github api anonymous access limits which happens during debugging/dev then add user and token here or sourced from a separate file
# . ~/githubapitoken
#GITHUB_USER=""
#GITHUB_TOKEN=""

function showver {
if [ -f "$1" ]; then
  CUR_VER=$("$1" version)
  if [ "$CUR_VER" ]; then
   echo Installed Version for $1 is $CUR_VER
  else
    echo WARNING unable to determine version for $1. Maybe wrong os/arch binary was installed
  fi
else
  echo No executable file at $1, unable to check version
fi
}

REPO=caddyserver/caddy

if [ "$GITHUB_TOKEN" != "" ]; then
echo using access token with script
echo $GITHUB_USER $GITHUB_TOKEN
fi

LOCAL=false
SAVE=false
FORCE=false

while getopts 'fslb:a:o:' OPTION; do
  case "$OPTION" in
    f)
      FORCE=true
      ;;
    s)
      SAVE=true
      ;;
    l)
      LOCAL=true
      ;;
    o)
      OS=$OPTARG
      echo setting os to $OS
      ;;
    b)
        BIN_NAME=$OPTARG
        echo using binary name $BIN_NAME
        ;;
    a)
      ARCH=$OPTARG
      echo setting architecture to $ARCH
    ;;
  esac
done

shift $(( OPTIND - 1 ))

if [ ! $OS ]; then
  echo determining operating system
  case "$OSTYPE" in
    darwin*)  OS=mac ;;
    linux*)   OS=linux ;;
    bsd*)     OS=freebsd ;;
    msys*)    OS=windows ;;
    *)
     echo "no release for : $OSTYPE"
     exit 0
    ;;
  esac
fi

if [ ! $OS ]; then
  echo No Operating System Specified, $OS
  exit 0
fi


if [ ! $ARCH ]; then
  echo determining system architecture
declare -A ARCHES
ARCHES=( ["arm64"]="arm64" ["aarch64"]="arm64"  ["x86_64"]="amd64" ["armv61"]="armv6"  ["armv71"]="armv7"  ["arm32"]="armv7"  ["armhf"]="armv7" )
ARCH=${ARCHES[$(uname -m)]}
  if [ ! $ARCH ]; then
    echo  Your machine kernel architecture $(uname -m) has no caddy release
    echo see https://github.com/caddyserver/caddy/releases
    exit 1
  fi
fi

ARCHIVE=tar.gz
[ "$OS" == "windows" ] && ARCHIVE=zip

echo Operating System $OS
echo Architecture $ARCH
echo Archive Type $ARCHIVE

REPO_DIR=$(dirname "$(dirname "$(readlink -f "$0")")") || exit
BIN_DIR="$REPO_DIR/bin"
BIN_NAME=${BIN_NAME:-caddy}
[ "$OS" == windows ] && BIN_NAME=$BIN_NAME.exe
BIN_PATH="$REPO_DIR/$BIN_NAME"

echo $BIN_PATH

if [ $LOCAL == true ]; then
 echo "Using Local Binary <$BIN_DIR/$OS-$ARCH> if Available"
   if [ -f "$BIN_DIR/$OS-$ARCH" ]; then
   \cp -f "$BIN_DIR/$OS-$ARCH" "$BIN_PATH"
   echo copying $BIN_DIR/$OS-$ARCH to $BIN_PATH
   showver $BIN_PATH
   exit 0
  else
    echo $BIN_DIR/$OS-$ARCH not available caddy binary not set
    exit 0
  fi
fi

RECORD=$(curl -u $GITHUB_USER:$GITHUB_TOKEN -s https://api.github.com/repos/$REPO/releases/latest)
NEW_VER=$(echo $RECORD | jq -r '.tag_name')
[ "$NEW_VER" ] && echo $NEW_VER is latest version available from  https://github.com/caddyserver/caddy/releases
if [ -f "$BIN_PATH" ] && [ "$SAVE" == false ]; then
echo checking current installed version
VER=$("$BIN_PATH" version)
  if [ "$VER" ] && [ "$NEW_VER" ]; then
    if [[ "$VER" == *"$NEW_VER"* ]]; then
     echo $BIN_PATH is current, "$NEW_VER"
       if [ "$FORCE" == true ]; then
         echo "forcing download/overwrite"
       else
         exit 0
       fi
    else
      echo updating $VER to $NEW_VER
    fi
  else
    echo unable to determine version for "$BIN_PATH" overwriting with $NEW_VER, $OS $ARCH
  fi
else
  echo "$BIN_PATH" does not exist, installing $NEW_VER
fi

URL=$(echo $RECORD | \
   jq -r \
   --arg os $OS \
   --arg arch $ARCH \
    --arg archive $ARCHIVE \
   '.assets[] | select(  .name | contains($os)) |
     select (.name | contains($arch)) |
     select (.name | contains($archive)) |
     .browser_download_url' \
   )

if [ $URL ]; then

echo "Downloading Archive $URL"

wget --user=-u $GITHUB_USER --password=$GITHUB_TOKEN -q $URL -P $BIN_DIR

ARC=$(basename $URL)
echo Extracting Caddy from Archive, $ARC
if [ $OS == windows ]; then
 unzip $BIN_DIR/$ARC caddy.exe
 if [ "$SAVE" == true ]; then
   mv caddy.exe -f "$BIN_DIR/$OS-$ARCH"
 fi
else
  tar -xzf $BIN_DIR/$ARC caddy
  chmod +x caddy
  if [ "$SAVE" == true ]; then
    mv caddy -f "$BIN_DIR/$OS-$ARCH"
  fi
fi

rm $BIN_DIR/$ARC



else
  echo no such release for $OS $ARCH
fi

if [ "$SAVE" == true ]; then
showver "$BIN_DIR/$OS-$ARCH"
else
  showver "$BIN_PATH"
fi
