#!/bin/bash

set -e

show_help() {
  cat << EOF

Simple tool to generate Mender Artifact suitable for docker Update Module

Usage: $0 [options] IMAGE [IMAGES...] [-- [options-for-mender-artifact] ]

    Options: [ -n|artifact-name -t|--device-type --software-name --software-version --software-filesystem --run-args -o|--output_path -h|--help ]

        --artifact-name       - Artifact name
        --device-type         - Target device type identification (can be given more than once)
        --software-name       - Name of the key to store the software version: rootfs-image.NAME.version,
                                instead of rootfs-image.docker.version
        --software-version    - Value for the software version, defaults to the name of the artifact
        --software-filesystem - If specified, is used instead of rootfs-image
        --run-args            - Command line args to add when running the container(s)
        --output-path         - Path to output file. Default: docker-artifact.mender
        --help                - Show help and exit
        IMAGE [IMAGES...]     - Docker container images to add to the Artifact

Anything after a '--' gets passed directly to the mender-artifact tool.

EOF
}

show_help_and_exit_error() {
  show_help
  exit 1
}

check_dependency() {
  if ! which "$1" > /dev/null; then
    echo "The $1 utility is not found but required to generate Artifacts." 1>&2
    return 1
  fi
}

if ! check_dependency mender-artifact; then
  echo "Please follow the instructions here to install mender-artifact and then try again: https://docs.mender.io/downloads#mender-artifact" 1>&2
  exit 1
fi
check_dependency docker
check_dependency jq

device_types=""
artifact_name=""
output_path="docker-artifact.mender"
meta_data_file="meta-data.json"
IMAGES=""
passthrough_args=""

while (( "$#" )); do
  case "$1" in
    --device-type | -t)
      if [ -z "$2" ]; then
        show_help_and_exit_error
      fi
      device_types="$device_types $1 $2"
      shift 2
      ;;
    --artifact-name | -n)
      if [ -z "$2" ]; then
        show_help_and_exit_error
      fi
      artifact_name=$2
      shift 2
      ;;
    --software-name | --software-version | --software-filesystem)
      if [ -z "$2" ]; then
        show_help_and_exit_error
      fi
      passthrough_args="$passthrough_args $1 $2"
      shift 2
      ;;
    --run-args)
      if [ -z "$2" ]; then
        show_help_and_exit_error
      fi
      run_args=$2
      shift 2
      ;;
    --output-path | -o)
      if [ -z "$2" ]; then
        show_help_and_exit_error
      fi
      output_path=$2
      shift 2
      ;;
    -h | --help)
      show_help
      exit 0
      ;;
    --)
      shift
      passthrough_args="$@"
      break
      ;;
    -*)
      echo "Error: unsupported option $1"
      show_help_and_exit_error
      ;;
    *)
      IMAGES="$IMAGES $1"
      shift
      ;;
  esac
done

if [ -z "${artifact_name}" ]; then
  echo "Artifact name not specified. Aborting."
  show_help_and_exit_error
fi

if [ -z "${device_types}" ]; then
  echo "Device type not specified. Aborting."
  show_help_and_exit_error
fi

if [ -z "${IMAGES}" ]; then
  echo "At least one Docker image must be specified. Aborting."
  show_help_and_exit_error
fi

HASHES=""
for image in $IMAGES; do
    docker pull $image
    HASHES="$HASHES\"$(docker inspect --format='{{index .RepoDigests 0}}' $image)\" "
done
HASHES=$(echo $HASHES | tr ' ' ',')

eval "jq -n --argjson c '[$HASHES]' '{\"containers\": \$c, \"run_args\": \"${run_args}\"}'" > $meta_data_file

mender-artifact write module-image \
  -T docker \
  $device_types \
  -o $output_path \
  -n $artifact_name \
  -m $meta_data_file \
  $passthrough_args

rm $meta_data_file

echo "Artifact $output_path generated successfully:"
mender-artifact read $output_path

exit 0
