#!/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
#

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

PROGRAM="$(basename $0)"

# 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')"
    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=$(ipfs add -q $MESSAGE)

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

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

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

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

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

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

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

	# So we now do the think almost again
	cat > zblock << EOF
{
    "block":"$BLOCK",
    "block_signature":"$BLOCK_SIGNATURE"
}
EOF
	ZBL="zblock"
	# and we add it on IPFS
	ZBLOCK=$(ipfs add -q $ZBL)
	echo $ZBLOCK
}

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

	# cat $PWD/zblock | json_pp
	# Optional or extending with
	# python send_as_ak_tx $ZBLOCK
	# or for "offline" use
	echo $ZBLOCK > $ZLATEST
	ipfs name publish --key=zchain $ZBLOCK > /dev/null 2>&1
    if [ "$?" -ne 0 ]
    then
        logit "[ERROR]" "Failed publishing ZBLOCK: $ZBLOCK"
        exit 1
    fi
	ipfs files ls /zarchive > /dev/null 2>&1
    if [ "$?" -ne 0 ]
    then
        logit "[WARNING]" "/zarchive does not exist"
        ipfs files mkdir /zarchive > /dev/null 2>&1
        if [ "$?" -ne 0 ]
        then
            logit "[ERROR]" "Could not create /zarchive directory. Aborting."
            exit 1
        fi
    fi
	ipfs files cp /zlatest /zarchive/$(date -u +%s)-$(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
	ipfs files rm /zlatest > /dev/null 2>&1
    if [ "$?" -ne 0 ]
    then
        logit "[ERROR]" "Could not remove previous /zlatest"
        exit 1
    fi
	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
else
	usage
	exit 0
fi