#!/usr/bin/env bash

# Run two node local net.
# Unlike the docker-compose script in the /docker folder, this version builds
# the nodes based on the current state of the code, instead of depending in a
# published version.

set -e

# chainspec defaults to ghost-local if no arguments are passed to this script;
# if arguments are passed in, the first is the chainspec
chainspec="${1:-ghost-local}"

# PROJECT_ROOT=$(git rev-parse --show-toplevel)
source "$(dirname "$0")"/common.sh

# cd "$PROJECT_ROOT"

last_modified_rust_file=$(
	find . -path ./target -prune -o -type f -name '*.rs' -printf '%T@ %p\n' |
	sort -nr |
	head -1 |
	cut -d' ' -f2-
)

ghost="target/release/ghost"

# ensure the ghost binary exists and is up to date
if [ ! -x "$ghost" ] || [ "$ghost" -ot "$last_modified_rust_file" ]; then
	# cargo build --release
    echo "[+] Build needed"
fi

# setup variables
node_offset=0
declare -a node_pids
declare -a node_pipes

# create a sed expression which injects the node name and stream type into
# each line
function make_sed_expr() {
	name="$1"
	type="$2"

	printf "s/^/%8s %s: /" "$name" "$type"
}

# turn a string into a flag
function flagify() {
	printf -- '--%s' "$(tr '[:upper:]' '[:lower:]' <<< "$1")"
}

# start a node and label its output
#
# this function takes a single argument, the node name.
# the name must be one of those which can be passed to the ghost binary, in
# un-flagged form, one of:
# 	alice, bob, charlie, dave, eve, ferdie, one, two
function run_node() {
	name="$1"
	# create a named pipe so we can get the node's PID  while also sedding
	# its output
	local stdout
	local stderr
	stdout=$(mktemp --dry-run --tmpdir)
	stderr=$(mktemp --dry-run --tmpdir)
	mkfifo "$stdout"
	mkfifo "$stderr"
	node_pipes+=("$stdout")
	node_pipes+=("$stderr")

	# compute ports from offset
	local port=$((30333+node_offset))
	local rpc_port=$((9933+node_offset))
	local ws_port=$((9944+node_offset))
	node_offset=$((node_offset+1))

    echo "$(flagify "$name")"
    echo "--node-key 000000000000000000000000000000000000000000000000000000000000000${node_offset}"
    
	# start the node
	# "$ghost" \
	# 	--chain "$chainspec" \
	# 	--tmp \
	# 	--port "$port" \
	# 	--rpc-port "$rpc_port" \
	# 	--rpc-cors all \
    # 	--node-key 0000000000000000000000000000000000000000000000000000000000000001 \
	# 	"$(flagify "$name")" \
	# > "$stdout" \
	# 2> "$stderr" \
	# &
	# local pid=$!
	# node_pids+=("$pid")
	#
	# # send output from the stdout pipe to stdout, prepending the node name
	# sed -e "$(make_sed_expr "$name" "OUT")" "$stdout" >&1 &
	# # send output from the stderr pipe to stderr, prepending the none name
	# sed -e "$(make_sed_expr "$name" "ERR")" "$stderr" >&2 &
}

# clean up the nodes when the script exits
function finish {
	for node_pid in "${node_pids[@]}"; do
		kill -9 "$node_pid"
	done

	for node_pipe in "${node_pipes[@]}"; do
		rm "$node_pipe"
	done
}
trap finish EXIT

# start the nodes
run_node Alice
run_node Bob

# now wait; this will exit on its own only if both subprocess exit
# the practical implication, as both subprocesses are supposed to run
# forever, is that this script will also run forever, until killed, ath which
# point the exit trap should kill the subprocesses
wait