#!/bin/sh

conv() {
	while [ $# -gt 0 ]; do
		if printf "%s" "$1" | grep -qE '^0b[0-1]+$'; then
			if [ "$m" -eq 0 ]; then	
				printf "Binary %s → Decimal: " "$1"
			fi
			t=$(printf "%s" "$1" | sed 's/^0b//')
			printf "ibase=2; %s / %s" "$t" "$k" | bc | tr -d '\n' && printf "%s\n" "$p"

		elif printf "%s" "$1" | grep -qE '^([0-9A-Fa-f]+|0x[0-9A-Fa-f]+)$'; then
			if [ "$m" -eq 0 ]; then
				printf "Hex %s → Decimal: " "$1"
			fi
			t=$(printf "%s" "$1" | sed 's/^0x//')
			printf "ibase=16; %s / %X" "$(printf "%s" "$t" | sed 'y/abcdef/ABCDEF/')" "0b$k" | bc | tr -d '\n' && printf "%s\n" "$p"

		else
			printf "Error: '%s' is not a valid decimal or hexadecimal number\n" "$1" >&2
			stat=1

		fi
		shift
	done
	return "$stat"
}


main() {
	USAGE="usage: ${0} [-mnKMG] ..."
	if ! [ "$1" = "x" ] && ! [ -t 0 ]; then
		cat | tr '\n' ' ' | xargs todec "x" "$@"
		return "$?"

	elif [ "$1" = "x" ]; then
		shift

	fi
	
	if [ $# -eq 0 ]; then
		printf "Error: No arguments provided\n%s\n" "$USAGE" >&2
		return 2

	fi
	
	stat=0	
	k=1; m=0; n=0; p='';
	while getopts "mnKMG" flag; do
		case "$flag" in
			m) m=1; ;;
		       	n) n=1; ;;
			# 1024
			K) k=10000000000; p='K'; ;;
			# 1 048 576
			M) k=100000000000000000000; p='M'; ;;
			# 1 073 741 824
			G) k=1000000000000000000000000000000; p='G'; ;;
			*) printf "%s\n" "$USAGE" >&2 ; return 2 ;;
		esac
	done

	shift $(( OPTIND - 1 ))
	
	t=$(conv "$@")
	stat=$?

	if [ "$n" -eq 1 ] && [ "$m" -eq 1 ]; then
		t=$(printf "%s" "$t" | tr '\n' ' ')

	elif [ "$n" -eq 1 ] && [ "$m" -eq 0 ]; then
		t=$(printf "%s" "$t" | tr '\n' ';')

	else
		t=$(printf "%s" "$t")

	fi
	
	printf "%s\n" "$t"	
	return "$stat"
}

main "$@"
