#!/usr/bin/env bash

# Shamelessly extract ASCII distro logos from neofetch
# (https://github.com/dylanaraps/neofetch)
# and convert them into C string constants.
# Requires bash for associative arrays, bleh.

# Takes a single argument: path to neofetch binary

set -e

usage () { echo "usage: `basename $0` path-to-neofetch" ; }

[ $# -eq 1 ] || { usage >&2 ; return 1 ; }

# Obviously, we're very sensitive to the exact contents of the neofetch
# script. We rely on:
#
# ...arbitrary text...
# ^get_distro_ascii() {$

# We set STARTED to non-empty upon hitting "get_distro_ascii()"
STARTED=""
# We set LOGOSTARTED to the line where the current logo starts, and unset it
# upon the logo's termination (discovered via ^EOF$).
LOGOSTARTED=""
LINE=0
LOGOS=0
# don't emit the same key more than once, or we'll get multiple definitions
declare -A KEYSSEEN
while IFS= read -r line ; do
	LINE=$((LINE + 1))
	if [ -z "$STARTED" ] ; then
		if [ "$line" = 'get_distro_ascii() {' ] ; then
			STARTED="$LINE"
			echo "#include \"ncart.h\""
			echo "#include <stdlib.h>"
			echo "#include <strings.h>"
			echo "// Output of \"`basename $0` $1\""
			echo "// Generated on `date -u`"
			echo "// Copyright Dylan Araps under an MIT License"
			echo "// Found get_distro_ascii at line $LINE"
		fi
	elif [ -z "$NAME" ] ; then
		NAME=`echo "$line" | sed -n -e 's/.*"\([^|]*\)"\*\?)$/\1/p'`
		if [ -n "$NAME" ] ; then
			echo "// Logo #$LOGOS: $NAME..."
			NAME=`echo $NAME | sed -e 's/\\\\/\\\\\\\\/g' | tr \  _ | tr / _ | tr -- - _`
			if [ -z "${KEYSSEEN[$NAME]}" ] ; then
				KEYSSEEN[$NAME]="$LINE"
				PRESERVE="$NAME"
			else
				echo "Warning, found duplicate name $NAME" >&2
			fi
		elif [ "$line" = "}" ] ; then # are we done with get_distro_ascii()?
			DONE="$LINE"
			echo "// Closed get_distro_ascii at line $LINE"
			break
		fi
	elif [ -z "$LOGOSTARTED" ]; then
		if echo "$line" | grep '^ *read -rd ' > /dev/null ; then
			LOGOS=$((LOGOS + 1))				# found the start of a new logo!
			LOGOSTARTED="$LINE"
			if [ -n "$PRESERVE" ] ; then
				echo -n "static const char $NAME[] = \""
			fi
		fi
	elif [ -n "$LOGOSTARTED" ]; then
		if [ "$line" = "EOF" ] ; then
			if [ -n "$PRESERVE" ] ; then
				echo "\";"
				echo "// $NAME: $((LINE - LOGOSTARTED)) lines, done at line $LINE."
			fi
			LOGOSTARTED=""
			NAME=""
			PRESERVE=""
		else
			if [ -n "$PRESERVE" ] ; then
				# FIXME don't eliminate the color templating once we carry colors
				/bin/echo -E -n "$line" | sed -e 's/\\/\\\\/g' -e 's/"/\\"/g' -e 's/${c.}//g' && /bin/echo -E -n '\n'
			fi
		fi
	fi
done < "$1"

# if DONE is defined, we ran to completion. yay! emit a table providing
# access to these strings via key comparison.
if [ -n "$DONE" ] ; then
	echo
	echo "struct neofetch_art { const char* oskey; const char* ncart; };"
	echo
	echo "const struct neofetch_art ncarts[] = {"
	for k in "${!KEYSSEEN[@]}" ; do
		echo "  { \"$k\", $k },"
	done
	echo "  { NULL, NULL }"
	echo "};"
	echo
	echo "const char* get_neofetch_art(const char* oskey){"
	echo "  for(const struct neofetch_art* nfa = ncarts ; nfa->oskey ; ++nfa){"
	echo "    if(strcasecmp(nfa->oskey, oskey) == 0){"
	echo "      return nfa->ncart;"
	echo "    }"
	echo "  }"
	echo "  return NULL;"
	echo "}"
	exit 0
fi

# unsurprisingly, this incredibly brittle code has broken. crap!
if [ -z "$STARTED" ] ; then
	echo "Failed; never found get_distro_ascii(). Alas..." >&2
else
	echo "Failed; never closed out get_distro_ascii(). Hrmm..." >&2
fi
exit 1
