#!/bin/bash
# This file describe the structure of the ArchingKaos messages in their basis.
#
# As previously thought, we exchange one IPFS hash through whatever means we can.
#
# GPG is mentioned as a signing algorithm for encryption, decryption and signing.
# Let's say we have a file named as `example`
#
# We can extend this with calling the encoder and further send the transaction
#

#AK_FINGERPRINT="CHANGE THIS TO YOUR DEFAULT AK_FINGERPRINT"
# We acquire the GPG fingerprint by email address
# The following example finds kaos@kaos.kaos' GPG fingerprint like this
# AK_FINGERPRINT="$(gpg2 --homedir $AK_GPGHOME --list-keys | grep kaos@kaos.kaos -1 | head -n1 | awk '{print $1}')"

PROGRAM="$(basename $0)"
set -xe

# Logging patch
logit(){
	ak-logthis "$PROGRAM" "$1" "$2"
}

# Below, the usage information
usage(){
	echo ""
	echo "Usage:"
	echo "$PROGRAM <action> <data_file>"
	echo ""
	echo "	Creates and publishes a ZBLOCK based on ACTION and DATA file."
	echo ""
	echo "		action		An action for the render to grasp"
	echo "		data_file	A data file that according to the action is valid"
	echo ""
	echo "#TODO:"
	echo "implement flags to change the inputs so we can manufacture"
	echo "zblocks directly from IPFS hashes refering to blocks."
}

main(){
    # We check firstly if the encapsulated value of the "ipfs" key has already
    # appeared in the zchain.
    TO_CHECK="$(cat $MESSAGE | jq | grep ipfs | awk '{print $2}' | sed -e 's/"//g;s/,//g')"
    ak-enter | jq | grep ipfs | awk '{print $2}' | sed -e 's/"//g;s/,//g' | sort | uniq > tempisalreadythere
    while IFS="" read -r p || [ -n "$p" ]
    do
        if [ "$p" == "$TO_CHECK" ]
        then
            logit "ERROR" "Value $TO_CHECK already mentioned on the zchain"
            exit 1
        fi
    done < tempisalreadythere
    rm tempisalreadythere

	logit "INFO" "We are doing $ACTION with content $MESSAGE"
	# We add it to IPFS
	MESSAGE_HASH=$(ak-ipfs-add $MESSAGE)

	# We create a detached and armor signature of it
	MESSAGE_SIGN_FILE=$MESSAGE".asc"
	gpg2 --homedir $AK_GPGHOME --detach-sign --sign-with $AK_FINGERPRINT --armor --output $MESSAGE_SIGN_FILE $MESSAGE

	# We add the signature to IPFS
	MESSAGE_SIGNATURE=$(ak-ipfs-add $MESSAGE_SIGN_FILE)

	# We will be using our public key also to put it in the block later
	KEY="gpg.pub"
	gpg2 --homedir $AK_GPGHOME --armour --output $KEY --export $AK_FINGERPRINT
	GPG_PUB_KEY=$(ak-ipfs-add $KEY)

	# Acquire last block of information, to chain this one with previous posted
	PREVIOUS=$(ak-ipfs-files-stat /zlatest | head -n 1)

	# We create a block of json like this:
    printf '{"timestamp":"%s","action":"%s","data":"%s","detach":"%s","gpg":"%s","previous":"%s"}' $(date -u +%s) $ACTION $MESSAGE_HASH $MESSAGE_SIGNATURE $GPG_PUB_KEY $PREVIOUS > block
	BLOCK="block"
	BLOCK_SIG=$BLOCK".asc"
	# We have a block now, so we sign it
	gpg2 --homedir $AK_GPGHOME --detach-sign --sign-with $AK_FINGERPRINT --armor --output $BLOCK_SIG $BLOCK

	# We now add the signature to IPFS
	BLOCK_SIGNATURE=$(ak-ipfs-add $BLOCK_SIG)

	# We also add the block!
	BLOCK=$(ak-ipfs-add $BLOCK)

	# So we now do the think almost again
	printf '{"block":"%s","block_signature":"%s"}' $BLOCK $BLOCK_SIGNATURE > zblock
	ZBL="zblock"
	# and we add it on IPFS
	ZBLOCK=$(ak-ipfs-add $ZBL)
	echo $ZBLOCK
}

if [ ! -z $2 ];
then
	MESSAGE="$2"
	ACTION="$1"
	if [ -f "$MESSAGE" ]; then
		main
	else
		logit "ERROR" "File does not exist. Aborting..."
		exit 1
	fi

	# cat $PWD/zblock | jq -M
	# Optional or extending with
	# python send_as_ak_tx $ZBLOCK
	# or for "offline" use
	echo $ZBLOCK > $AK_ZLATEST
	ak-ipfs-name-publish --key=zchain $ZBLOCK > /dev/null 2>&1
    if [ "$?" -ne 0 ]
    then
        logit "ERROR" "Failed publishing ZBLOCK: $ZBLOCK"
        exit 1
    fi
	ak-ipfs-files-ls /zarchive > /dev/null 2>&1
    if [ "$?" -ne 0 ]
    then
        logit "WARNING" "/zarchive does not exist"
        ak-ipfs-files-mkdir /zarchive > /dev/null 2>&1
        if [ "$?" -ne 0 ]
        then
            logit "ERROR" "Could not create /zarchive directory. Aborting."
            exit 1
        fi
    fi
	ak-ipfs-files-cp /zlatest /zarchive/$(date -u +%s)-$(ak-ipfs-files-stat /zlatest | head -n 1) > /dev/null 2>&1
    if [ "$?" -ne 0 ]
    then
        logit "ERROR" "Could not back up previous /zlatest"
        exit 1
    fi
	ak-ipfs-files-rm /zlatest > /dev/null 2>&1
    if [ "$?" -ne 0 ]
    then
        logit "ERROR" "Could not remove previous /zlatest"
        exit 1
    fi
	ak-ipfs-files-cp /ipfs/$ZBLOCK /zlatest > /dev/null 2>&1
    if [ "$?" -ne 0 ]
    then
        logit "ERROR" "Could not copy $ZBLOCK to /zlatest"
        exit 1
    fi
    ak-config publish
    if [ "$?" -ne 0 ]
    then
        logit "ERROR" "Could not publish new configuration"
        exit 1
    fi
else
	usage
	exit 0
fi