#!/bin/bash

# create OVA by default
CREATE_OVA="true"

# create components individually
# if CREATE_OVA is true these will be created implicitely
CREATE_OVF="false"
CREATE_MF="false"
CREATE_VMDK="false"

fail() {
    echo "$1"
    exit 1
}

create_ova()
{
    img_list=(${RAW_IMAGES})
    if [[ "${CREATE_VMDK}" = "true" || "${CREATE_OVA}" = "true" ]] ; then
        # TODO: tools version
        for img in ${img_list[@]} ; do
            name=${img%.*} # remove extension
            echo "running 'vmdk-convert'"
            echo "VMDKCONVERT_COMPRESSION_LEVEL=${VMDKCONVERT_COMPRESSION_LEVEL}"
            echo "VMDKCONVERT_NUM_THREADS=${VMDKCONVERT_NUM_THREADS}"
            time vmdk-convert ${img} ${name}.vmdk || fail "'vmdk-convert ${img} ${name}.vmdk' failed with $?"
            echo "done with 'vmdk-convert'"
        done
    fi

    if [[ "${CREATE_OVA}" = "true" || "${CREATE_OVF}" = "true" ]] ; then
        img0=${img_list[0]}
        name0=${img0%.*}

        if [ "${CREATE_OVA}" = "true" ] ; then
            output_file=${OVA_NAME}.ova
        else
            output_file=${OVA_NAME}.ovf
        fi

        ova_compose_args=()
        if [ "${CREATE_MF}" = "true" ] ; then
            ova_compose_args+=("--manifest")
        fi
        if [ -n "${SIGN_SCRIPT}" ] ; then
            ova_compose_args+=("--sign-script" "${SIGN_SCRIPT}")
        fi

        params=("--param" "disk=${name0}.vmdk")
        for p in "${PARAMS[@]}" ; do
            params+=("--param")
            params+=("$p")
        done

        echo "running 'ova-compose'"
        printf "%s\0" "${params[@]}" "${ova_compose_args[@]}" | xargs -t -0 ova-compose -i ${OVA_CFG_FILE} -o ${output_file} || \
            fail "ova-compose failed with $?"
        echo "done with 'ova-compose'"

        # nuke vmdk's if we created an OVA
        if [ "${CREATE_OVA}" = "true" ] ; then
            for img in ${img_list[@]} ; do
                name=${img%.*}
                rm -f ${name}.vmdk
            done
        fi
    fi
}

usage() {
    echo "Usage: $0"
    echo "          [--installer-config <config-file>] (ks file used for create-image)"
    echo "          [--installer-param key=val [...]] (params for parsing the ks file)"
    echo "          [--mf]"
    echo "          [--raw-image <image-file>]"
    echo "          [--ova-name <name>]"
    echo "          [--ova-config <ova-config-file>] (required)"
    echo "          [--ovf] (create OVF, do not create OVA)"
    echo "          [--param key=val [...]] (for ova-compose)"
    echo "          [--sign-script <script>] (script to sign the ova file)"
    echo "          [--vmdk-only] (don't use, use --vmdk)"
    echo "          [--vmdk] (convert raw image(s) to vmdk, do not create OVA)"
}

OPTS=$(getopt -o h --long compression-level:,installer-config:,installer-param:,num-threads:,raw-images:,ova-config:,ova-name:,param:,ovf,mf,vmdk-only,sign-script: -n $0 -- "$@")
if [ $? != 0 ] ; then
    usage
    echo "Terminating." >&2
    exit 1
fi

eval set -- "$OPTS"

while true; do
    case "$1" in
        --compression-level) VMDKCONVERT_COMPRESSION_LEVEL=${2}; shift 2 ;;
        -h)                  usage ; exit 0;;
        --installer-config)  CFG_FILE=${2} ; shift 2 ;;
        --installer-param)   INSTALLER_PARAMS+=("${2}"); shift 2 ;;
        --mf)                CREATE_MF="true"; shift ;;
        --num-threads)       VMDKCONVERT_NUM_THREADS=${2}; shift 2 ;;
        --raw-images)        RAW_IMAGES=${2} ; shift 2 ;;
        --ova-config)        OVA_CFG_FILE=${2} ; shift 2 ;;
        --ova-name)          OVA_NAME=${2} ; shift 2 ;;
        --ovf)               CREATE_OVF="true"; CREATE_OVA="false"; shift ;;
        --param)             PARAMS+=("${2}"); shift 2 ;;
        --sign-script)       SIGN_SCRIPT=${2}; shift 2 ;;
        --vmdk)              CREATE_VMDK="true"; CREATE_OVA="false"; shift ;;
        --vmdk-only)         CREATE_VMDK="true"; CREATE_OVA="false"; shift ;;
        --)                  shift; break ;;
        *)                   break ;;
    esac
done

echo  "${OVA_CFG_FILE}"

# will be used by vmdk-convert
export VMDKCONVERT_COMPRESSION_LEVEL
export VMDKCONVERT_NUM_THREADS

if [ -z "${OVA_CFG_FILE}" ] ; then
    echo "need an OVA config file" >&2
    usage
    echo "Terminating." >&2
    exit 1
fi

if [ -z "${OVA_NAME}" ] ; then
    ova_params=()
    for p in "${PARAMS[@]}" ; do
        ova_params+=("--param")
        ova_params+=("$p")
    done
    OVA_NAME=$(printf "%s\0" "${ova_params[@]}" | xargs -0 yjson -i ${OVA_CFG_FILE} | jq -r '.system.name')
fi

if [[ -z "${RAW_IMAGES}" && -z "${CFG_FILE}" ]] ; then
    echo "need a config file or image" >&2
    usage
    echo "Terminating." >&2
    exit 1
fi

if [ -z "${RAW_IMAGES}" ] ; then
    ks_params=()
    for p in "${INSTALLER_PARAMS[@]}" ; do
        ks_params+=("--param")
        ks_params+=("$p")
    done
    RAW_IMAGES=$(printf "%s\0" "${ks_params[@]}" | xargs -0 yjson -i ${CFG_FILE} | jq -r '.disks|values[].filename')
fi

if [ -z "${RAW_IMAGES}" ] ; then
    echo "no suitable image found" >&2
    usage
    echo "Terminating." >&2
    exit 1
fi

create_ova
