#!/usr/bin/env bash

: '
	This script tests whether uploaded parts can be skipped in a
	CompleteMultipartUpload

	On Minio: yes, parts can be skipped

	On S3: not tested

	Sample output (on Minio):

		f23911bcd1230f5ebe8887cbf5bc396e  part1
		a2657143167eaf647c40473e78a091dc  part4
		72f72c02c5163bc81024b28ac818c5e0  part5
		e29cf500d20498218904b8df8806caa2  part6
		Upload ID: e8fe7b83-9800-46fb-ae90-9d7ccd42fe76
		PART 1 ETag: "f23911bcd1230f5ebe8887cbf5bc396e"
		PART 4 ETag: "a2657143167eaf647c40473e78a091dc"
		PART 5 ETag: "72f72c02c5163bc81024b28ac818c5e0"
		PART 6 ETag: "e29cf500d20498218904b8df8806caa2"
		======================================== COMPLETE ====
		{
			"Location": "http://localhost:9000/test/upload",
			"Bucket": "test",
			"Key": "upload",
			"ETag": "\"48246e44d4b38bdc2f3c10ee25b1af17-3\""
		}
		======================================== GET FULL ====
		{
			"AcceptRanges": "bytes",
			"LastModified": "2023-04-25T10:54:35+00:00",
			"ContentLength": 31457280,
			"ETag": "\"48246e44d4b38bdc2f3c10ee25b1af17-3\"",
			"ContentType": "binary/octet-stream",
			"Metadata": {}
		}
		97fb904da7ad310699a6afab0eb6e061  get-full
		97fb904da7ad310699a6afab0eb6e061  -
		======================================== GET PART 3 ====
		{
			"AcceptRanges": "bytes",
			"LastModified": "2023-04-25T10:54:35+00:00",
			"ContentLength": 10485760,
			"ETag": "\"48246e44d4b38bdc2f3c10ee25b1af17-3\"",
			"ContentRange": "bytes 20971520-31457279/31457280",
			"ContentType": "binary/octet-stream",
			"Metadata": {},
			"PartsCount": 3
		}
		e29cf500d20498218904b8df8806caa2  get-part3

	Conclusions:

	- Skipping a part in a CompleteMultipartUpload call is OK
	- The part is simply not included in the stored object
	- Sequential part renumbering counts only non-skipped parts
'

export AWS_ACCESS_KEY_ID=1D8Pk2k4oQSoh1BU
export AWS_SECRET_ACCESS_KEY=4B46SR8U7FUgY0raB8Zuxg1NLyLTvbNV

function aws { command aws --endpoint-url http://localhost:9000 $@ ; }

aws --version

aws s3 mb s3://test

for NUM in 1 4 5 6; do
	dd if=/dev/urandom of=part$NUM bs=1M count=10
done
md5sum part*

UPLOAD=$(aws s3api create-multipart-upload --bucket test --key 'upload' | jq -r ".UploadId")
echo "Upload ID: $UPLOAD"

PARTS=""

for NUM in 1 4 5 6; do
	ETAG=$(aws s3api upload-part --bucket test --key 'upload' --part-number $NUM \
		--body "part$NUM" --upload-id "$UPLOAD" | jq -r ".ETag")
	echo "PART $NUM ETag: $ETAG"
	if [ "$NUM" != "5" ]; then
		if [ -n "$PARTS" ]; then
			PARTS="$PARTS,"
		fi
		PARTS="$PARTS {\"ETag\":$ETAG,\"PartNumber\":$NUM}"
	fi
done

echo "======================================== COMPLETE ===="
echo "{\"Parts\":[$PARTS]}" > mpu
aws s3api complete-multipart-upload --multipart-upload file://mpu \
		--bucket test --key 'upload' --upload-id "$UPLOAD"

echo "======================================== GET FULL ===="
aws s3api get-object --bucket test --key upload get-full
md5sum get-full
cat part1 part4 part6 | md5sum

echo "======================================== GET PART 3 ===="
aws s3api get-object --bucket test --key upload --part-number 3 get-part3
md5sum get-part3
