#!/bin/bash

RELEASE_VERSION="5.0"
CREATE_OVF="false"
CREATE_MF="false"
VMDK_ONLY="false"
SRC_REPO_URL=""
SYSTEM_ARCH="$(uname -m)"

init_env()
{
    #map system arch to docker arch
    if [ $SYSTEM_ARCH = "aarch64" ]; then
        SYSTEM_ARCH="arm64"
    else
        SYSTEM_ARCH="amd64"
    fi

    #map user arch to docker arch
    if [ -n "${ARCH}" ] ; then
        if [ ${ARCH} = "aarch64" ]; then
            ARCH="arm64"
        elif [ ${ARCH} = "x86_64" ]; then
            ARCH="amd64"
        else
            echo "$ARCH is not valid. setting system arch"
	    ARCH=$SYSTEM_ARCH
        fi
    else
        ARCH=$SYSTEM_ARCH
        echo "setting default system arch: $ARCH"
    fi

    cd ${POI_PATH}/docker || exit 1
    #set POI_IMAGE_NAME if empty
    if [ -z "${POI_IMAGE_NAME}" ] ; then
        POI_IMAGE_NAME="photon/installer"
        echo "using default POI_IMAGE_NAME: $POI_IMAGE_NAME"
    else
        echo "using exported POI_IMAGE_NAME: $POI_IMAGE_NAME"
    fi

    #check POI_IMAGE_NAME if already exists
    if [ "$ARCH" = "$SYSTEM_ARCH" ]; then
        sudo docker inspect "$POI_IMAGE_NAME" > /dev/null
    else
        sudo docker inspect "$ARCH/$POI_IMAGE_NAME" > /dev/null
    fi

    if [ $? -ne 0 ]; then
        echo "building $POI_IMAGE_NAME container image..."

        #In case of arch and system arch is same build POI_IMAGE_NAME container
        if [ $ARCH = $SYSTEM_ARCH ]; then
            sudo docker buildx build --build-context poi-helper=${POI_PATH} -t $POI_IMAGE_NAME .
        else
            sudo docker buildx build --build-context poi-helper=${POI_PATH} --platform=linux/$ARCH -t $ARCH/$POI_IMAGE_NAME .
        fi
        echo "...done"
    else
        echo "$POI_IMAGE_NAME container image already exists"
    fi
}

create_repo_and_raw_image()
{
    exec_docker_cmd=""

    #create repo path if not exist
    cd ${POI_PATH}/examples/${IMAGE_FLAVOR} || exit 1
    if [ ! -d "${LOCAL_REPO_PATH}" ] ; then
        echo "repo $RELEASE_VERSION does not exist"
        mkdir -p ${LOCAL_REPO_PATH}
    else
        echo "repo path already exist: ${LOCAL_REPO_PATH}"
	echo "=================================="
    fi

    # create local repo only when remote repo url is empty
    if [ -z "${SRC_REPO_URL}" ] ; then
        if [ $ARCH = $SYSTEM_ARCH ]; then
            exec_docker_cmd="sudo docker run --rm --privileged -v/dev:/dev -v$(pwd):/workdir -v ${LOCAL_REPO_PATH}:/repo $POI_IMAGE_NAME create-repo -c ${KS_CONFIG_FILE} -v ${RELEASE_VERSION}"
        else
            exec_docker_cmd="sudo docker run --rm --privileged -v/dev:/dev -v$(pwd):/workdir -v ${LOCAL_REPO_PATH}:/repo $ARCH/$POI_IMAGE_NAME create-repo -c ${KS_CONFIG_FILE} -v ${RELEASE_VERSION}"
        fi

        echo "downloading $RELEASE_VERSION repo..."
        echo "$exec_docker_cmd"
        $exec_docker_cmd
        echo "=================================="
    else
        echo "using public repo: ${SRC_REPO_URL}"
        echo "=================================="
    fi


    if [ $ARCH = $SYSTEM_ARCH ]; then
        exec_docker_cmd="sudo docker run --rm --privileged -v/dev:/dev -v$(pwd):/workdir -v ${LOCAL_REPO_PATH}:/repo $POI_IMAGE_NAME create-image -c ${KS_CONFIG_FILE} -v ${RELEASE_VERSION}"
    else
        exec_docker_cmd="sudo docker run --rm --privileged -v/dev:/dev -v$(pwd):/workdir -v ${LOCAL_REPO_PATH}:/repo $ARCH/$POI_IMAGE_NAME create-image -c ${KS_CONFIG_FILE} -v ${RELEASE_VERSION}"
    fi

    # create raw image using public repo
    if [ -n "${SRC_REPO_URL}" ] ; then
        exec_docker_cmd="$exec_docker_cmd --repo-paths=$SRC_REPO_URL"
    fi

    echo "building raw image..."
    echo "$exec_docker_cmd"
    $exec_docker_cmd
    echo "=================================="
}

create_flavor_image()
{
    exec_docker_cmd=""

    #select container to run docker command based on arch
    if [ $ARCH = $SYSTEM_ARCH ]; then
        exec_docker_cmd="sudo docker run --rm --privileged -v/dev:/dev -v$(pwd):/workdir -v ${LOCAL_REPO_PATH}:/repo $POI_IMAGE_NAME"
    else
	exec_docker_cmd="sudo docker run --rm --privileged -v/dev:/dev -v$(pwd):/workdir -v ${LOCAL_REPO_PATH}:/repo $ARCH/$POI_IMAGE_NAME"
    fi

    if [ $IMAGE_FLAVOR = "azure" ]; then
	#build azure
        exec_docker_cmd="$exec_docker_cmd create-azure --raw-image ${RAW_IMAGE}"
    elif [ $IMAGE_FLAVOR = "ova" ]; then
        #build ova
	exec_docker_cmd="$exec_docker_cmd create-ova --installer-config ${KS_CONFIG_FILE} --ova-config ${OVA_CONFIG} --ova-name ${OVA_NAME} --raw-image ${RAW_IMAGE}"

	#build ovf
	if [[ "$CREATE_OVF" = "true" && "$VMDK_ONLY" != "true" ]]; then
    exec_docker_cmd="$exec_docker_cmd --ovf"
	fi

	#build manifest file, applicable for ovf
        if [[ "$VMDK_ONLY" != "true" && "$CREATE_MF" = "true" ]]; then
            exec_docker_cmd="$exec_docker_cmd --mf"
	fi

	#build vmdk
	if [[ "$CREATE_OVF" != "true" && "$VMDK_ONLY" = "true" ]]; then
            exec_docker_cmd="$exec_docker_cmd --vmdk-only"
	fi
    fi

    echo "Trigger image builder command..."
    echo "=================================="
    echo "$exec_docker_cmd"
    $exec_docker_cmd
}


usage() {
    echo "Usage: $0"
    echo "          [--raw-image <image-file>] (required)"
    echo "          [--config-file <ks-config-file>] (required)"
    echo "          [--local-repo-path <local-repo-path>] (required)"
    echo "          [--poi-path <poi-path>] (required)"
    echo "          [--src-repo-url <src-repo-url>] (optional, use this parameter in case of public repo)"
    echo "          [--flavor <image-flavor>] (required)"
    echo "          [--ova-config <ova-config>] (required in case of ova)"
    echo "          [--ova-name <ova-name>] (required in case of ova)"
    echo "          [--ovf <set true>] (optional parameter for ova flavor, required in case of building ovf cant use along with --vmdk-only)"
    echo "          [--mf <set true>] (optional parameter for ova flavor, required in case of building manifest file)"
    echo "          [--vmdk-only <set true>] (optional parameter for ova flavor, required in case of building vmdk cant use along with --ovf)"
    echo "          [--arch <arch-type>] (optional parameter for building aarch64 or x86_64 images. accept aarch64 or x86_64 as value by default uses system arch)"
    echo "          [--releasever <release-version>] (optional parameter by default image build for 5.0)"
    echo "~~~~~~~~~~~~~~~~~~~~~~~~~~~EXAMPLE~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"
    echo "============================================================"
    echo         "           create AZURE image              "
    echo "============================================================"
    echo                     "create 5.0 AZURE"
    echo "$0 --raw-image photon-azure.raw --config-file azure_ks.yaml --local-repo-path /home/dbx/poi/repo/5.0 --poi-path /home/dbx/workspace/poi_gitlab/photon-os-installer/ --flavor azure"
    echo "-------------------------------------------------------------"
    echo                     "create 4.0 AZURE"
    echo "$0 --raw-image photon-azure-4.0.raw --config-file azure_40_ks.yaml --local-repo-path /home/dbx/poi/repo/4.0 --poi-path /home/dbx/workspace/poi_gitlab/photon-os-installer/ --flavor azure --releasever 4.0"
    echo "-------------------------------------------------------------"
    echo                     "create 4.0 AZURE with remote repo"
    echo "$0 --raw-image photon-azure-4.0.raw --config-file azure_40_ks.yaml --local-repo-path /home/dbx/poi/repo/4.0 --poi-path /home/dbx/workspace/poi_gitlab/photon-os-installer/ --flavor azure --releasever 4.0 --src-repo-url=https://packages.vmware.com/photon/4.0/photon_updates_4.0_x86_64/"
    echo "============================================================"
    echo         "           create OVA image              "
    echo "============================================================"
    echo                     "create 5.0 OVA"
    echo "$0 --raw-image minimal.img --config-file minimal_ks.yaml --local-repo-path /home/dbx/poi/repo/5.0 --poi-path /home/dbx/workspace/poi_gitlab/photon-os-installer/ --flavor ova --ova-config minimal.yaml --ova-name minimal"
    echo "-------------------------------------------------------------"
    echo                     "create 4.0 OVA"
    echo "$0 --raw-image minimal.img --config-file minimal_ks.yaml --local-repo-path /home/dbx/poi/repo/4.0 --poi-path /home/dbx/workspace/poi_gitlab/photon-os-installer/ --flavor ova --ova-config minimal.yaml --ova-name minimal --releasever 4.0"
    echo "-------------------------------------------------------------"
    echo                     "create 4.0 OVA with remote repo"
    echo "$0 --raw-image minimal.img --config-file minimal_ks.yaml --local-repo-path /home/dbx/poi/repo/4.0 --poi-path /home/dbx/workspace/poi_gitlab/photon-os-installer/ --flavor ova --ova-config minimal.yaml --ova-name minimal --releasever 4.0 --src-repo-url=https://packages.vmware.com/photon/4.0/photon_updates_4.0_x86_64/"
    echo "============================================================"
    echo         "           create VMDK only              "
    echo "============================================================"
    echo                     "create 5.0 VMDK"
    echo "$0 --raw-image minimal.img --config-file minimal_ks.yaml --local-repo-path /home/dbx/poi/repo/5.0 --poi-path /home/dbx/workspace/poi_gitlab/photon-os-installer/ --flavor ova --ova-config minimal.yaml --ova-name minimal --vmdk-only"
    echo "-------------------------------------------------------------"
    echo                     "create 4.0 VMDK"
    echo "$0 --raw-image minimal.img --config-file minimal_ks.yaml --local-repo-path /home/dbx/poi/repo/4.0 --poi-path /home/dbx/workspace/poi_gitlab/photon-os-installer/ --flavor ova --ova-config minimal.yaml --ova-name minimal --vmdk-only --releasever 4.0"
    echo "-------------------------------------------------------------"
    echo                     "create 4.0 VMDK with remote repo"
    echo "$0 --raw-image minimal.img --config-file minimal_ks.yaml --local-repo-path /home/dbx/poi/repo/4.0 --poi-path /home/dbx/workspace/poi_gitlab/photon-os-installer/ --flavor ova --ova-config minimal.yaml --ova-name minimal --vmdk-only --releasever 4.0 --src-repo-url=https://packages.vmware.com/photon/4.0/photon_updates_4.0_x86_64/"
    echo "============================================================"
    echo         "           create OVF image and manifest file    "
    echo         " Note: Creating OVF required to first build VMDK from above command line"
    echo "============================================================"
    echo                     "create 5.0 OVF"
    echo "$0 --raw-image minimal.img --config-file minimal_ks.yaml --local-repo-path /home/dbx/poi/repo/5.0 --poi-path /home/dbx/workspace/poi_gitlab/photon-os-installer/ --flavor ova --ova-config minimal.yaml --ova-name minimal --ovf --mf"
    echo "-------------------------------------------------------------"
    echo                     "create 4.0 OVF"
    echo "$0 --raw-image minimal.img --config-file minimal_ks.yaml --local-repo-path /home/dbx/poi/repo/4.0 --poi-path /home/dbx/workspace/poi_gitlab/photon-os-installer/ --flavor ova --ova-config minimal.yaml --ova-name minimal --ovf --mf --releasever 4.0"
    echo "-------------------------------------------------------------"
    echo                     "create 4.0 OVF with remote repo"
    echo "$0 --raw-image minimal.img --config-file minimal_ks.yaml --local-repo-path /home/dbx/poi/repo/4.0 --poi-path /home/dbx/workspace/poi_gitlab/photon-os-installer/ --flavor ova --ova-config minimal.yaml --ova-name minimal --ovf --mf --releasever 4.0 --src-repo-url=https://packages.vmware.com/photon/4.0/photon_updates_4.0_x86_64/"
    echo "============================================================"
    echo         "           create AMI image              "
    echo "============================================================"
    echo                     "create 5.0 AMI"
    echo "$0 --config-file ami_ks.yaml --local-repo-path /home/dbx/poi/repo/5.0 --poi-path /home/dbx/workspace/poi_gitlab/photon-os-installer/ --flavor ami"
    echo "-------------------------------------------------------------"
    echo                     "create 4.0 AMI"
    echo "$0 --config-file ami_40_ks.yaml --local-repo-path /home/dbx/poi/repo/4.0 --poi-path /home/dbx/workspace/poi_gitlab/photon-os-installer/ --flavor ami --releasever 4.0"
    echo "-------------------------------------------------------------"
    echo                     "create 4.0 AMI with remote repo"
    echo "$0 --config-file ami_40_ks.yaml --local-repo-path /home/dbx/poi/repo/4.0/ --poi-path /home/dbx/workspace/poi_gitlab/photon-os-installer/ --flavor ami --releasever 4.0 --src-repo-url=https://packages.vmware.com/photon/4.0/photon_updates_4.0_x86_64/"
    echo "============================================================"
    echo         "           create RPI image              "
    echo "============================================================"
    echo                     "create 5.0 RPI"
    echo "$0 --config-file rpi_ks.yaml --local-repo-path /home/dbx/poi/repo/5.0 --poi-path /home/dbx/workspace/poi_gitlab/photon-os-installer/ --flavor rpi --arch aarch64"
    echo "-------------------------------------------------------------"
    echo                     "create 4.0 RPI"
    echo "$0 --config-file rpi_ks.yaml --local-repo-path /home/dbx/poi/repo/4.0 --poi-path /home/dbx/workspace/poi_gitlab/photon-os-installer/ --flavor rpi --arch aarch64 --releasever 4.0"
    echo "-------------------------------------------------------------"
    echo                     "create 4.0 RPI with remote repo"
    echo "$0 --config-file rpi_ks.yaml --local-repo-path /home/dbx/poi/repo/4.0 --poi-path /home/dbx/workspace/poi_gitlab/photon-os-installer/ --flavor rpi --arch aarch64 --releasever 4.0 --src-repo-url=https://packages.vmware.com/photon/4.0/photon_updates_4.0_x86_64/"
    echo "============================================================"

}

OPTS=$(getopt -o h --long raw-image:,config-file:,local-repo-path:,poi-path:,src-repo-url:,flavor:,ova-config:,ova-name:,arch:,ovf,mf,vmdk-only,releasever: -n $0 -- "$@")
if [ $? != 0 ] ; then
    usage
    echo "Terminating." >&2
    exit 1
fi

eval set -- "$OPTS"

while true; do
    echo $1
    case "$1" in
        -h) usage; exit 0;;
        --raw-image) RAW_IMAGE=${2}; shift 2;;
        --config-file) KS_CONFIG_FILE=${2}; shift 2;;
        --local-repo-path) LOCAL_REPO_PATH=${2}; shift 2;;
        --poi-path) POI_PATH=${2}; shift 2;;
        --src-repo-url) SRC_REPO_URL=${2}; shift 2;;
        --flavor) IMAGE_FLAVOR=${2}; shift 2;;
        --ova-config) OVA_CONFIG=${2}; shift 2;;
        --ova-name) OVA_NAME=${2}; shift 2;;
        --arch) ARCH=${2}; shift 2;;
        --ovf) CREATE_OVF="true"; shift;;
        --mf) CREATE_MF="true"; shift;;
        --vmdk-only) VMDK_ONLY="true"; shift;;
        --releasever) RELEASE_VERSION=${2}; shift 2;;
        --) shift; break ;;
        *) break ;;
    esac
done

if [ -z "${RAW_IMAGE}" ]; then
    if [[ "$IMAGE_FLAVOR" != "ami" && "$IMAGE_FLAVOR" != "rpi" ]] ; then
        echo "raw image is missing" >&2
        usage
        echo "Terminating." >&2
        exit 1
    fi
fi

if [ -z "${KS_CONFIG_FILE}" ] ; then
    echo "config file is missing" >&2
    usage
    echo "Terminating." >&2
    exit 1
fi

if [ -z "${LOCAL_REPO_PATH}" ] ; then
    echo "repo path is missing" >&2
    usage
    echo "Terminating." >&2
    exit 1
fi

if [ -z "${POI_PATH}" ] ; then
    echo "poi path is missing" >&2
    usage
    echo "Terminating." >&2
    exit 1
fi

if [ -z "${IMAGE_FLAVOR}" ] ; then
    echo "image flavor is missing" >&2
    usage
    echo "Terminating." >&2
    exit 1
fi

if [ ${IMAGE_FLAVOR} = "ova" ] ; then
    if [[ -z "${OVA_CONFIG}" || -z "${OVA_NAME}" ]] ; then
        echo "ova config or ova name is missing" >&2
        usage
        echo "Terminating." >&2
        exit 1
    fi

    if [[ "$CREATE_OVF" = "true" && "$VMDK_ONLY" = "true" ]] ; then
        echo "cannot use simultaneously, either --ovf or --vmdk-only can be used at once" >&2
        usage
        echo "Terminating." >&2
        exit 1
    fi
fi

#Initialize container environment
init_env

#Create repository and raw image
create_repo_and_raw_image

#Create final image
if [[ "${IMAGE_FLAVOR}" = "ova" || "${IMAGE_FLAVOR}" = "azure" ]] ; then
    create_flavor_image
fi
