#!/usr/bin/env bash

# Unofficial Bash Strict Mode
# http://redsymbol.net/articles/unofficial-bash-strict-mode/
set -euo pipefail
IFS=$'\n\t'
# End of Unofficial Bash Strict Mode

# defaults
input_separator=$'\t'
output_separator=','
master_separator=$'\t'
group_by_column=''
detail_column=''
# defaults

# Helper functions
die() {
    printf -- "$@" >&2
    printf '\n' >&2
    exit 1
}

show_help_and_die() {
    error_message="${1:-}"
    help_message="Syntax:
    ... | $0 [-s INPUT_SEPARATOR] [-o OUTPUT_SEPARATOR] [-m MASTER_SEPARATOR] -g GROUP_COLUMN -d DETAILS_COLUMN

Options:
    -s : What is the separator between input columns. Defaults to \\t.
    -o : What should be used as separator between group name and detail values in output. Defaults to ','.
    -m : What should be used in output before group name and details. Defaults to \\t.
    -g : Which column (numbers start from 1) should be used to define group
    -d : Which column (numbers start from 1) contain values to group"

    if [[ -n "${error_message}" ]]
    then
        printf "Error:\n    %s\n\n" "${error_message}" >&2
        echo "${help_message}" >&2
        exit 1
    fi

    echo "${help_message}"
    exit 0
}
# Helper functions

# MAIN PROGRAM

## Parse and validate command line arguments
while getopts 's:g:d:o:m:h?' opt "$@"
do
    case "${opt}" in
        s)
            input_separator="${OPTARG}"
            ;;
        g)
            group_by_column="${OPTARG}"
            ;;
        d)
            detail_column="${OPTARG}"
            ;;
        o)
            output_separator="${OPTARG}"
            ;;
        m)
            master_separator="${OPTARG}"
            ;;
        h|?)
            show_help_and_die
            ;;
    esac
done

[[ -n "${group_by_column}" ]] || die "You didn't provide group by column!"
[[ "${group_by_column}" =~ ^[1-9][0-9]*$ ]] || die "Group by column has to be positive integer, and not: [%s]!" "${group_by_column}"

[[ -n "${detail_column}" ]] || die "You didn't provide details column!"
[[ "${detail_column}" =~ ^[1-9][0-9]*$ ]] || die "Details column has to be positive integer, and not: [%s]!" "${detail_column}"

declare -a values

exec awk -v"os=${output_separator}" -v"hs=${master_separator}" -F"${input_separator}" "
    BEGIN { count=0 }
    {
        g=\$${group_by_column};
        v=\$${detail_column};
        if ( g in details ) {
            details[g] = details[g] os v;
        } else {
            order[count]=g;
            count++;
            details[g]=v;
        }
    }
    END {
        for (i=0; i < count; i++) {
            group=order[i];
            printf \"%s%s%s\\n\", group, hs, details[group]
        }
    }
"

# vim: set ft=sh:
