#!/usr/bin/env zsh

# ensure there is only one match for a particular ingredient.
# $1: ingredient name
function checkIngredientName
{
    local matches
    matches=$(pantry --exact-match \
                     --search name $1 \
                     --print name \
                     master )
    matches=(${(f)matches})
    if [[ -z ${matches} ]]; then
        echo No matches for ingredient $1 1>&2
        exit 1
    elif [[ ${#matches} -ne 1 ]]; then
        echo More than one match for ingredient $1. Matches: 1>&2
        echo ${(F)matches} 1>&2
        exit 1
    fi
}

# make sure recipe name is not already in file.
function checkRecipeName
{
    local matches
    if [[ -z $1 ]]; then
        echo Name trait for recipe not given. 1>&2
        exit 1
    fi
    matches=$( pantry --exact-match \
               --search name $1 \
               --print name \
               $COLLECTIONS 2>/dev/null)
    if [[ -n $matches ]]; then
        echo Food or recipe named $1 already exists. 1>&2
        exit 1
    fi
}

# add ingredient to temporary list.
# $1: ingredient name
# $2: ingredient qty
# $3: ingredient unit
# $4: ingredient comment
function addToTemp
{
    if [[ -z $SOURCE ]]; then
        echo Missing source for ingredients. 1>&2
        exit 1
    fi
    pantry --exact-match \
           --search name $1 \
           --change quantity $2 \
           --change unit $3 \
           --change comment "$4" \
           --add $TEMPORARY \
           --auto-order \
           $SOURCE
}

function createRecipe
{
    local args collection traitName traitValue unitName unitValue

    args=( --create
           --exact-match
           --add-ingredients $TEMPORARY )

    if [[ -z $COLLECTIONS ]]; then
        echo COLLECTIONS variable not set. 1>&2
        exit 1
    fi

    for collection in ${COLLECTIONS}; do
        args+=(--add $collection)
    done

    for traitName traitValue in ${(kv)TRAITS}
    do
        # hold off on doing change if unit is serving
        if [[ ($traitName == unit) && ($traitValue == serving) ]]; then
            args+=(--change unit g )
        else
            args+=(--change $traitName $traitValue )
        fi
    done

    for unitName unitValue in $UNITS; do
        args+=(--change-avail-unit $unitName $unitValue)
    done

    pantry $args
}

function addServingUnit
{
    local yield perServing
    yield=$( pantry --exact-match \
                    --search name ${TRAITS[name]} \
                    --print recipe \
                    ${COLLECTIONS[1]} |

             grep 'Yield: ' |
             cut -d' ' -f 2 )

    yield=${yield%g}

    perServing=$(( yield / $SERVINGS ))
    if [[ (-z $perServing) || ($perServing -le 0) ]]; then
        echo Calculation of per serving gram weight failed. 1>&2
        exit 1
    fi

    pantry --edit \
           --search name ${TRAITS[name]} \
           --change-avail-unit serving $perServing \
           $COLLECTIONS
}

function printResult
{
    pantry --exact-match \
           --search name ${TRAITS[name]} \
           --print name \
           --print info \
           --print recipe \
           --print nuts \
           --print units \
           ${COLLECTIONS[1]}
}

function changeUnitToServing
{
    pantry --exact-match \
           --search name ${TRAITS[name]} \
           --edit \
           --change unit serving \
           $COLLECTIONS
}

for filename
do
    typeset -A TRAITS
    source $filename
    if [[ $(( ${#INGREDIENTS} % 4 )) -ne 0 ]]
    then
        echo "Error reading $filename each ingredient needs 4 fields" 1>&2
        exit 1
    fi

    if [[ -z $TEMPORARY ]]; then
        echo TEMPORARY variable not set. 1>&2
        exit 1
    fi
    checkRecipeName ${TRAITS[name]}

    pantry --delete $TEMPORARY 2>/dev/null

    local name qty unit comment
    for name qty unit comment in "$INGREDIENTS[@]"
    do
        checkIngredientName $name
        addToTemp $name $qty $unit "$comment"
    done
    
    createRecipe
    [[ -n $SERVINGS ]] && addServingUnit
    [[ ${TRAITS[unit]} == serving ]] && changeUnitToServing

    printResult

done
