#!/usr/bin/env bash
set -euo pipefail

##########################################################
################## Check dependencies ####################
##########################################################

check_dependencies () {
  for cmd in "$@"; do
    if ! command -v $cmd >/dev/null 2>&1; then
      echo "This script requires \"${cmd}\" to be installed"
      exit 1
    fi
  done
}

if [ ! "$(uname -s)" == "Linux" ]; then
  echo "Sorry, Umbrel only supports Linux-based systems at this point."
  echo
  echo "You may work around this by modifying the configuration script yourself, but it's highly experimental."
  echo "If you get it working, we hope you consider making a PR. :)"
  exit 1
fi

check_dependencies docker docker-compose dirname readlink

# Switch to Umbrel's root directory
UMBREL_ROOT="$(readlink -f "$(dirname "${BASH_SOURCE[0]}")"/..)"
if [[ ! -d "$UMBREL_ROOT" ]]; then
  echo "Root dir does not exist '$UMBREL_ROOT'"
  exit 1
fi
cd "$UMBREL_ROOT"

# Configure for mainnet or testnet or regtest depending
# upon the user-supplied value of $NETWORK
BITCOIN_NETWORK="${NETWORK:-mainnet}"

if [ "$BITCOIN_NETWORK" != "mainnet" ] && [ "$BITCOIN_NETWORK" != "testnet" ] && [ "$BITCOIN_NETWORK" != "regtest" ]; then
  echo "Error: Umbrel can only be configured for mainnet (default), testnet or regtest"
  exit 1
fi

echo
echo "======================================"
if [[ -f "${UMBREL_ROOT}/statuses/configured" ]]; then
  echo "=========== RECONFIGURING ============"
else
  echo "============ CONFIGURING ============="
fi
echo "========= UMBREL (${NETWORK}) ==========="
echo "======================================"
echo


##########################################################
############### Setup configuration files ###############
##########################################################

# Store paths to intermediary config files
BITCOIN_CONF_FILE="./templates/bitcoin.conf"
LND_CONF_FILE="./templates/lnd.conf"
TOR_CONF_FILE="./templates/torrc"
ENV_FILE="./templates/.env"

# Remove intermediary files if they exist from any
# previous unclean configuration run
[[ -f "$BITCOIN_CONF_FILE" ]] && rm -f "$BITCOIN_CONF_FILE"
[[ -f "$LND_CONF_FILE" ]] && rm -f "$LND_CONF_FILE"
[[ -f "$TOR_CONF_FILE" ]] && rm -f "$TOR_CONF_FILE"
[[ -f "$ENV_FILE" ]] && rm -f "$ENV_FILE"

# Copy template configs to intermediary configs
[[ -f "./templates/bitcoin-sample.conf" ]] && cp "./templates/bitcoin-sample.conf" "$BITCOIN_CONF_FILE"
[[ -f "./templates/lnd-sample.conf" ]] && cp "./templates/lnd-sample.conf" "$LND_CONF_FILE"
[[ -f "./templates/torrc-sample" ]] && cp "./templates/torrc-sample" "$TOR_CONF_FILE"
[[ -f "./templates/.env-sample" ]] && cp "./templates/.env-sample" "$ENV_FILE"


##########################################################
############ Generate configuration variables ############
##########################################################

# Generate RPC credentials
echo "Generating auth credentials"
echo
BITCOIN_RPC_USER="umbrelrpc"
BITCOIN_RPC_DETAILS=$("./scripts/rpcauth.py" "$BITCOIN_RPC_USER")
BITCOIN_RPC_AUTH=$(echo "$BITCOIN_RPC_DETAILS" | head -2 | tail -1)
BITCOIN_RPC_PASS=$(echo "$BITCOIN_RPC_DETAILS" | tail -1)
BITCOIN_RPC_PORT=8332
BITCOIN_P2P_PORT=8333

# Pull Tor image and generate Tor password
echo "Generating Tor password"
echo
docker pull --quiet getumbrel/tor:v0.4.1.9
TOR_PASS=$("./scripts/rpcauth.py" "itdoesntmatter" | tail -1)
TOR_HASHED_PASS=$(docker run --rm getumbrel/tor:v0.4.1.9 --quiet --hash-password "$TOR_PASS")


##########################################################
### Update config files with configuration variables #####
##########################################################

if [ "$BITCOIN_NETWORK" == "testnet" ]; then
  # Set testnet ports
  BITCOIN_RPC_PORT=18332
  BITCOIN_P2P_PORT=18333
  # Uncomment "test" block
  sed -i "s/\#\[test\]/\[test\]/g;" "$BITCOIN_CONF_FILE"
  # Enable testnet
  sed -i "s/\#testnet=1/testnet=1/g" "$BITCOIN_CONF_FILE"
  # Switch LND to testnet
  sed -i "s/bitcoin.mainnet=1/bitcoin.testnet=1/g;" "$LND_CONF_FILE"
  # Comment mainnet neutrino peers
  sed -i "s/neutrino.addpeer=bb2.breez.technology/\;neutrino.addpeer=bb2.breez.technology/g;" "$LND_CONF_FILE"
  sed -i "s/neutrino.addpeer=mainnet1-btcd.zaphq.io/\;neutrino.addpeer=mainnet1-btcd.zaphq.io/g;" "$LND_CONF_FILE"
  sed -i "s/neutrino.addpeer=mainnet2-btcd.zaphq.io/\;neutrino.addpeer=mainnet2-btcd.zaphq.io/g;" "$LND_CONF_FILE"
  # Uncomment testnet neutrino peers
  sed -i "s/\;neutrino.addpeer=testnet1-btcd.zaphq.io/neutrino.addpeer=testnet1-btcd.zaphq.io/g;" "$LND_CONF_FILE"
  sed -i "s/\;neutrino.addpeer=testnet2-btcd.zaphq.io/neutrino.addpeer=testnet2-btcd.zaphq.io/g;" "$LND_CONF_FILE"

fi

if [ "$BITCOIN_NETWORK" == "regtest" ]; then
  # Set regtest ports
  BITCOIN_RPC_PORT=18443
  BITCOIN_P2P_PORT=18444
  # Uncomment "regtest" block
  sed -i "s/\#\[regtest\]/\[regtest\]/g;" "$BITCOIN_CONF_FILE"
  # Enable regtest
  sed -i "s/\#regtest=1/regtest=1/g" "$BITCOIN_CONF_FILE"
  # Switch LND to regtest
  sed -i "s/bitcoin.mainnet=1/bitcoin.regtest=1/g;" "$LND_CONF_FILE"
  # Use bitcoind as the node
  sed -i "s/bitcoin.node=neutrino/bitcoin.node=bitcoind/g;" "$LND_CONF_FILE"
fi

# Update RPC and P2P Ports
sed -i "s/rpcport=<port>/rpcport=$BITCOIN_RPC_PORT/g;" "$BITCOIN_CONF_FILE"
sed -i "s/port=<port>/port=$BITCOIN_P2P_PORT/g;" "$BITCOIN_CONF_FILE"
sed -i "s/BITCOIN_RPC_PORT=<port>/BITCOIN_RPC_PORT=$BITCOIN_RPC_PORT/g;" "$ENV_FILE"
sed -i "s/BITCOIN_P2P_PORT=<port>/BITCOIN_P2P_PORT=$BITCOIN_P2P_PORT/g;" "$ENV_FILE"

# Add rpcauth to bitcoin.conf
sed -i "s/rpcauth=<rpcauth>/$BITCOIN_RPC_AUTH/g;" "$BITCOIN_CONF_FILE"
# Add RPC credentials to lnd.conf
sed -i "s/bitcoind.rpcuser=<username>/bitcoind.rpcuser=$BITCOIN_RPC_USER/g;" "$LND_CONF_FILE"
sed -i "s/bitcoind.rpcpass=<password>/bitcoind.rpcpass=$BITCOIN_RPC_PASS/g;" "$LND_CONF_FILE"
# Add RPC credentials to env file
sed -i "s/BITCOIN_RPC_USER=<username>/BITCOIN_RPC_USER=$BITCOIN_RPC_USER/g;" "$ENV_FILE"
sed -i "s/BITCOIN_RPC_PASS=<password>/BITCOIN_RPC_PASS=$BITCOIN_RPC_PASS/g;" "$ENV_FILE"

# Add chain to env file
sed -i "s/BITCOIN_NETWORK=<network>/BITCOIN_NETWORK=$BITCOIN_NETWORK/g;" "$ENV_FILE"

# Add Tor password
sed -i "s/HashedControlPassword <password>/HashedControlPassword $TOR_HASHED_PASS/g;" "$TOR_CONF_FILE"
sed -i "s/torpassword=<password>/torpassword=$TOR_PASS/g;" "$BITCOIN_CONF_FILE"
sed -i "s/tor.password=<password>/tor.password=$TOR_PASS/g;" "$LND_CONF_FILE"
sed -i "s/TOR_PASSWORD=<password>/TOR_PASSWORD=$TOR_PASS/g;" "$ENV_FILE"
sed -i "s/TOR_HASHED_PASSWORD=<password>/TOR_HASHED_PASSWORD=$TOR_HASHED_PASS/g;" "$ENV_FILE"


##########################################################
############### Performance optimizations ################
##########################################################

echo
echo "Making performance optimizations"
echo

echo "Setting dbcache size"
echo
DBCACHE_SIZE=$(awk '/MemTotal/{printf "%d\n", ($2/2^10 * 0.5) - 300}' /proc/meminfo)
sed -i -e "s/dbcache=<size>/dbcache=$DBCACHE_SIZE/g" "$BITCOIN_CONF_FILE"

# TODO: Adjust prune size based on available disk space

##########################################################
############## Override main config files ################
##########################################################

mv -f "$BITCOIN_CONF_FILE" "./bitcoin/bitcoin.conf"
mv -f "$LND_CONF_FILE" "./lnd/lnd.conf"
mv -f "$TOR_CONF_FILE" "./tor/torrc"
mv -f "$ENV_FILE" "./.env"


##########################################################
################ Configuration complete ##################
##########################################################

echo "Pulling Umbrel Docker images"
echo
docker-compose pull --quiet

# Create configured status
touch "$UMBREL_ROOT"/statuses/configured

echo "Configuration successful"
echo "You can now start Umbrel by running:"
echo "  sudo ./scripts/start"
echo