#!/bin/bash

profileKeyGen="default"
profileEnc="default"

if [ $# -le 2 ] || [ $2 != '-v' ]; then
    echo "Usage: test.sh sop.binary -v <int verbosity> [profile generate-key] [profile encryption]"
    exit 1
fi

if [ ! -z "$4" ]; then
    profileKeyGen=$4
fi

if [ ! -z "$4" ]; then
    profileEnc=$5
fi

sop=$1
which $sop
if [ $? != 0 ]; then
    echo "gosop not found."; echo
    echo "Did you run go install? Is \$GOPATH/bin in your \$PATH?"
    echo "... else, you can set sop=/path/to/gosop/binary in scripts/tests.sh"; echo
    exit 1
fi

verbosity=$3

# tmp directory, erased on exit
create_tmp_dir() {
    eval $1="$(mktemp -d)"
    if [ $? != 0 ]; then
        echo "Failed to create temporary directory"
        exit $?
    fi
}

erase_tmp_dir() {
    rm -rf $1
    if [ $? != 0 ]; then
        echo "Failed to delete temporary directory: $1"
        exit $?
    fi
}


check_exit_code() {
    if [ $1 == 69 ] || [ $1 == 37 ]; then
        printf "    ... SKIPPED \n"
        return 0
    fi

    if [ $1 != $2 ]; then
        echo "Failed: Exit code $1, expected $2"
        exit $1
    fi
    echo "    ... OK"
}

comm() {
    printf "$ $1\n"
}

my_cat() {
    if [ $verbosity == 1 ]; then
        head -n1 $1
    fi
    if [ $verbosity == 2 ]; then
        cat $1
    fi
}

create_tmp_dir data
trap "erase_tmp_dir $data" EXIT

# Test files
message=$data/message.txt
password=$data/password.txt
alice_secret=$data/alice.sec
bob_secret=$data/bob.sec
alice_public=$data/alice.asc
bob_public=$data/bob.asc
bob_public_unarmored=$data/bob.bin
session_key=$data/session.bin
signed=$data/signed.asc
verified=$data/verified.asc
encrypted=$data/encrypted.asc
encrypted_with_password=$data/encrypted_with_password.asc
verification=$data/verification.txt
bad_verification=$data/bad_verification.txt
verification_too_old=$data/verification_too_old.txt
verification_too_young=$data/verification_too_young.txt
decrypted_with_password=$data/decrypted_password.txt
decrypted_with_key=$data/decrypted.txt
decrypted_with_session_key=$data/decrypted.txt
unarmored=$data/unarmored.bin
signatures=$data/signatures.pgp

printf "\nOír la noche inmensa, más inmensa sin ella.\nY el verso cae al alma como al pasto el rocío.\n" > $message
printf "test.123" > $password

comm "version"
$sop version
check_exit_code $? 0

comm "list-profiles generate-key"
$sop list-profiles generate-key
check_exit_code $? 0

comm "list-profiles encrypt"
$sop list-profiles encrypt
check_exit_code $? 0

comm "generate-key --no-armor"
$sop generate-key --no-armor --profile=$profileKeyGen --with-key-password=$password 'Bob Lovelace <bob@openpgp.example>' > $bob_secret
check_exit_code $? 0

comm "generate-key --no-armor"
$sop generate-key --no-armor --profile=$profileKeyGen --with-key-password=$password 'Bob Lovelace <bob@openpgp.example>' > $bob_secret
check_exit_code $? 0

comm "generate-key"
$sop generate-key --profile=$profileKeyGen --with-key-password=$password 'Alice Lovelace <alice@openpgp.example>' > $alice_secret
check_exit_code $? 0
my_cat $alice_secret

comm "extract-cert"
$sop extract-cert < $alice_secret > $alice_public
check_exit_code $? 0
my_cat $alice_public

comm "extract-cert --no-armor"
$sop extract-cert --no-armor < $bob_secret > $bob_public_unarmored
check_exit_code $? 0

comm "sign"
$sop sign --as=text --with-key-password=$password $alice_secret < $message > $encrypted
check_exit_code $? 0
my_cat $encrypted

comm "verify"
$sop verify $encrypted $alice_public < $message > $verification
check_exit_code $? 0
my_cat $verification

comm "verify corrupt"
tr a-z A-Z < $message | $sop verify $encrypted $alice_public > $bad_verification
check_exit_code $? 3
my_cat $bad_verification

comm "verify --not-after"
$sop verify --not-after=20060102T150405Z $encrypted $alice_public < $message > $verification_too_old
check_exit_code $? 3
my_cat $verification_too_old

sleep 1
comm "verify --not-before"
$sop verify --not-before=now $encrypted $alice_public < $message > $verification_too_young
check_exit_code $? 3
my_cat $verification_too_young

comm "inline-sign --as=clearsigned"
$sop inline-sign --as=clearsigned --with-key-password=$password $alice_secret < $message > $signed
check_exit_code $? 0
my_cat $signed

comm "inline-verify clearsigned"
$sop inline-verify --verifications-out=$verification $alice_public < $signed > $verified
check_exit_code $? 0
my_cat $verification
my_cat $verified
diff $message $verified
check_exit_code $? 0

comm "inline-detach clearsigned"
$sop inline-detach --signatures-out=$signatures < $signed > $verified
check_exit_code $? 0
diff $message $verified
check_exit_code $? 0
my_cat $signatures
$sop verify $signatures $alice_public < $message > $verification
check_exit_code $? 0
my_cat $verification

comm "inline-detach --no-armor clearsigned"
$sop inline-detach --no-armor --signatures-out=$signatures < $signed > $verified
check_exit_code $? 0
diff $message $verified
check_exit_code $? 0
my_cat $signatures
$sop verify $signatures $alice_public < $message > $verification
check_exit_code $? 0
my_cat $verification

comm "inline-sign --as=text"
$sop inline-sign --as=text --with-key-password=$password $alice_secret < $message > $signed
check_exit_code $? 0
my_cat $signed | my_cat

comm "inline-verify text"
$sop inline-verify --verifications-out=$verification $alice_public < $signed > $verified
check_exit_code $? 0
my_cat $verification
my_cat $verified
diff $message <( tr -d '\r' < $verified )
check_exit_code $? 0

comm "inline-detach text"
$sop inline-detach --signatures-out=$signatures < $signed > $verified
check_exit_code $? 0
diff $message <( tr -d '\r' < $verified )
check_exit_code $? 0
my_cat $signatures
$sop verify $signatures $alice_public < $message > $verification
check_exit_code $? 0
my_cat $verification

comm "inline-detach --no-armor text"
$sop inline-detach --no-armor --signatures-out=$signatures < $signed > $verified
check_exit_code $? 0
diff $message <( tr -d '\r' < $verified )
check_exit_code $? 0
my_cat $signatures
$sop verify $signatures $alice_public < $message > $verification
check_exit_code $? 0
my_cat $verification

comm "inline-sign --as=binary"
$sop inline-sign --as=binary --with-key-password=$password $alice_secret < $message > $signed
check_exit_code $? 0
my_cat $signed | my_cat

comm "inline-verify binary"
$sop inline-verify --verifications-out=$verification $alice_public < $signed > $verified
check_exit_code $? 0
my_cat $verification
my_cat $verified
diff $message $verified
check_exit_code $? 0

comm "inline-detach binary"
$sop inline-detach --signatures-out=$signatures < $signed > $verified
check_exit_code $? 0
diff $message $verified
check_exit_code $? 0
my_cat $signatures
$sop verify $signatures $alice_public < $message > $verification
check_exit_code $? 0
my_cat $verification

comm "inline-detach --no-armor binary"
$sop inline-detach --no-armor --signatures-out=$signatures < $signed > $verified
check_exit_code $? 0
diff $message $verified
check_exit_code $? 0
my_cat $signatures
$sop verify $signatures $alice_public < $message > $verification
check_exit_code $? 0
my_cat $verification

comm "encrypt --with-password"
$sop encrypt --with-password=$password --profile=$profileEnc < $message > $encrypted_with_password
check_exit_code $? 0
my_cat $encrypted_with_password

comm "decrypt --with-password"
$sop decrypt --with-password=$password < $encrypted_with_password > $decrypted_with_password
check_exit_code $? 0
my_cat $decrypted_with_password

comm "encrypt"
$sop encrypt --profile=$profileEnc $alice_public < $message > $encrypted
check_exit_code $? 0
my_cat $encrypted

comm "decrypt"
$sop decrypt --with-key-password=$password $alice_secret < $encrypted > $decrypted_with_key
check_exit_code $? 0
my_cat $decrypted_with_key

comm "decrypt --as=text --sign-with"
$sop encrypt --as=mime --sign-with=$alice_secret --with-key-password=$password $alice_public < $message > $encrypted
check_exit_code $? 0
my_cat $encrypted

comm "decrypt --session-key-out --verify-with --verifications-out"
$sop decrypt --session-key-out=$session_key --verify-with=$alice_public --verifications-out=$verification --with-key-password=$password $alice_secret < $encrypted > $decrypted_with_key
check_exit_code $? 0
my_cat $decrypted_with_key
my_cat $verification

comm "decrypt --with-session-key"
$sop decrypt --with-session-key=$session_key < $encrypted > $decrypted_with_session_key
check_exit_code $? 0
my_cat $decrypted_with_session_key

comm "armor"
$sop armor < $bob_public_unarmored > $bob_public
check_exit_code $? 0
my_cat $bob_public

comm "dearmor"
$sop dearmor < $encrypted > $unarmored
check_exit_code $? 0
