#!/usr/bin/env bash

function usage()
{
	cat <<EOF >&2
Usage:  $0 [options]

Options:
     -h                   Display help or usage
     -i <input_config>    Input config file
     -l <variable_list>   List of variables in the array (Optional)
EOF
	exit 1;
}

# Command line options
CONFIG_FILE=""
VAR_LIST=""

while getopts "hi:l:" o; do
	case "${o}" in
	h)
		usage
		;;
	i)
		CONFIG_FILE=${OPTARG}
		;;
	l)
		VAR_LIST=${OPTARG}
		;;
	*)
		usage
		;;
	esac
done
shift $((OPTIND-1))

if [ -z "${CONFIG_FILE}" ]; then
	echo "Must specify input config file"
	usage
fi

if [ ! -f "${CONFIG_FILE}" ]; then
	echo "The input config file should be a present"
	usage
fi

# use single awk script to run conversion, but leave in .sh file as awk is
# bad for getopt, and leaves the original script name alone.

awk -v"CONFIG_FILE=${CONFIG_FILE}" -v "SCRIPT_NAME=`basename $0`" -v"VARLIST=${VAR_LIST}" '
function array_length(a)
{
    result = 0

    for (i in a)
	result++

    return result
}

function get_fields(start, end)
{
    result = $start;

    for (nr = start+1; nr <= end; nr++) {
	result = result " " $nr
    }
    return result;
}

BEGIN {
      split(VARLIST,VAR_LIST," ")
}

# process items from the config file

/^HEADER:/	{ TYPE_HEADER = $2 }
/^TYPE:/	{ TYPE_NAME = get_fields(2, NF); }
/^NAME:/	{ ARRAY_NAME = $2}
/^MEMBER-NAME:/	{ MEMBER_NAME = $2 }
/^MEMBER-TYPE:/ { MEMBER_TYPE = get_fields(2, NF); }

# code to dump the generated .c file once config file is processed

END {
    # enable for debug
    if (length(ENVIRON["CARRAY_DEBUG"]) > 0) {
	print "ARRAY_NAME  " ARRAY_NAME > "/dev/stderr"
	print "TYPE_HEADER " TYPE_HEADER > "/dev/stderr"
	print "TYPE_NAME   " TYPE_NAME > "/dev/stderr"

	print "VAR_LIST length is " array_length(VAR_LIST) > "/dev/stderr"
	for (v in VAR_LIST) {
	    print "VAR_LIST " v  " = " VAR_LIST[v] > "/dev/stderr"
	}
    }

    if (array_length(VAR_LIST) == 0) {
	print "Warning; no VAR list on command line"  > "/dev/stderr"
    }

    if (length(ARRAY_NAME) == 0) {
	print "Must specify NAME: in input config file"  > "/dev/stderr"
	exit 1
    }

    if (length(TYPE_NAME) == 0) {
	print "Must specify TYPE: in input config file"  > "/dev/stderr"
	exit 1
    }

    if (length(TYPE_HEADER) == 0) {
	print "Must specify HEADER: in input config file"  > "/dev/stderr"
	exit 1
    }

    if (length(MEMBER_NAME) > 0 && length(MEMBER_TYPE) == 0) {
	print "Must specify MEMBER-TYPE: when using MEMBER-NAME:" > "/dev/stderr"
	exit 1
    }

    printf "// Generated with %s from %s\n", SCRIPT_NAME, CONFIG_FILE
    printf "// DO NOT EDIT THIS FILE DIRECTLY\n"
    printf "\n"
    printf("#include <%s>\n\n", TYPE_HEADER)

    for (v in VAR_LIST) {
	printf("extern %s %s;\n", TYPE_NAME, VAR_LIST[v])
    }
    print ""

    if (length(MEMBER_TYPE) > 0) {
	TYPE_NAME = MEMBER_TYPE;
    }

    if (length(MEMBER_NAME) > 0) {
	VAR_SUFFIX = "." MEMBER_NAME;
    } else {
	VAR_SUFFIX = ""
    }

    printf("%s *const %s[] = {\n", TYPE_NAME, ARRAY_NAME)
    for (v in VAR_LIST) {
	printf("\t&%s%s,\n", VAR_LIST[v], VAR_SUFFIX)
    }
    printf("\tNULL\n");

    printf("};\n");
}
' < ${CONFIG_FILE} || usage

