#!/usr/bin/env bash
###
### arching-kaos-tools
### Tools to interact and build an Arching Kaos Infochain
### Copyright (C) 2021 - 2025  kaotisk
###
### This program is free software: you can redistribute it and/or modify
### it under the terms of the GNU General Public License as published by
### the Free Software Foundation, either version 3 of the License, or
### (at your option) any later version.
###
### This program is distributed in the hope that it will be useful,
### but WITHOUT ANY WARRANTY; without even the implied warranty of
### MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
### GNU General Public License for more details.
###
### You should have received a copy of the GNU General Public License
### along with this program.  If not, see <http://www.gnu.org/licenses/>.
###
source $AK_LIBDIR/_ak_log
source $AK_LIBDIR/_ak_ipfs
source $AK_LIBDIR/_ak_config
source $AK_LIBDIR/_ak_settings

export AK_FINGERPRINT="$(_ak_settings_get gpg.fingerprint)"

_ak_gpg(){
    gpg2 --homedir $AK_GPGHOME $*
}

_ak_gpg_check_or_create(){
    _ak_gpg --list-keys | grep kaos@kaos.kaos -B 1
    if [ $? -ne 0 ]
    then
        _ak_gpg --batch --passphrase '' --quick-gen-key kaos@kaos.kaos rsa3072 sign 0
        FINGERPRINT="$(_ak_gpg --list-keys | grep kaos@kaos.kaos -B 1 | head -n 1 | awk '{print $1}')"
        _ak_gpg --batch --passphrase '' --quick-add-key $FINGERPRINT rsa3072 encrypt 0
    fi
}

_ak_gpg_create_key(){
    _ak_log_debug "Key name: $1"
    if [ -z $1 ] || [ ! -n "$1" ]
    then
        _ak_log_error "No email label was given"
        exit 1
    fi
    _ak_gpg --list-secret-keys | grep -F $1 >/dev/null 2>&1
    if [ $? -eq 0 ]
    then
        _ak_log_error "Key exists with the same email label"
        exit 1
    fi
    _ak_gpg --batch --passphrase '' --quick-gen-key $1 rsa4096 sign 0
    FINGERPRINT="$(_ak_gpg --list-keys | grep $1 -B 1 | head -n 1 | awk '{print $1}')"
    _ak_gpg --batch --passphrase '' --quick-add-key $FINGERPRINT rsa4096 encrypt 0
}

_ak_gpg_key_import_from_file(){
    if [ -z $1 ]
    then
        _ak_log_error "No argument given"
        exit 1
    fi
    if [ ! -n "$1" ]
    then
        _ak_log_error "Empty argument given"
        exit 1
    fi
    if [ ! -f "$AK_IPFS_ARTIFACTS/$1" ]
    then
        _ak_log_error "File not found"
        exit 1
    fi
    _ak_gpg --import $AK_IPFS_ARTIFACTS/$1 > /dev/null 2>&1
}

_ak_gpg_key_self_get_fingerprint_from_config(){
    _ak_config_show | jq -r '.gpg'
}

_ak_gpg_key_self_get_fingerprint(){
    if [ -z $1 ]
    then
        _ak_ipfs_cat "$(_ak_gpg_key_self_get_fingerprint_from_config)" | \
            _ak_gpg --show-keys 2>&1 | \
            head -n 2 | \
            tail -n 1 | \
            sed 's/ //g'
    else
        exit 1
    fi
}

_ak_gpg_key_get_fingerprint_from_ipfs(){
    if [ -n "$1" ]
    then
        _ak_ipfs_cat "$1" | \
            _ak_gpg --show-keys 2>&1 | \
            head -n 2 | \
            tail -n 1 | \
            sed 's/ //g'
    else
        exit 1
    fi
}

_ak_gpg_sign(){
    if [ ! -z $1 ] && [ -n "$1" ] && [ ! -z $2 ] && [ -n "$2" ]
    then
        _ak_gpg --sign --sign-with $AK_FINGERPRINT --armor --output $1 $2
    else
        exit 1
    fi
}

_ak_gpg_sign_detached(){
    if [ ! -z $1 ] && [ -n "$1" ] && [ ! -z $2 ] && [ -n "$2" ]
    then
        _ak_gpg --detach-sign --sign-with $AK_FINGERPRINT --armor --output $1 $2
    else
        _ak_log_error "Not enough arguments"
        exit 1
    fi
}

_ak_gpg_sign_clear(){
    if [ ! -z $1 ] && [ -n "$1" ] && [ ! -z $2 ] && [ -n "$2" ]
    then
        _ak_gpg --clear-sign --sign-with $AK_FINGERPRINT --armor --output $1 $2
    else
        exit 1
    fi
}

_ak_gpg_encrypt_sign(){
    if [ ! -z $1 ] && [ -n "$1" ] && [ ! -z $2 ] && [ -n "$2" ] && [ ! -z $3 ] && [ -n "$3" ]
    then
        _ak_gpg --sign-with $AK_FINGERPRINT --encypt -r $3 --armor --output $1 $2
    else
        exit 1
    fi
}

_ak_gpg_encrypt_sign_for_self(){
    if [ ! -z $1 ] && [ -n "$1" ] && [ ! -z $2 ] && [ -n "$2" ]
    then
        _ak_gpg --sign-with $AK_FINGERPRINT --encypt -r $AK_FINGERPRINT --armor --output $1 $2
    else
        exit 1
    fi
}

_ak_gpg_encrypt(){
    if [ ! -z $1 ] && [ -n "$1" ] && [ ! -z $2 ] && [ -n "$2" ] && [ ! -z $3 ] && [ -n "$3" ]
    then
        _ak_gpg --encypt -r $3 --armor --output $1 $2
    else
        exit 1
    fi
}

_ak_gpg_encrypt_for_self(){
    if [ ! -z $1 ] && [ -n "$1" ] && [ ! -z $2 ] && [ -n "$2" ]
    then
        _ak_gpg --encypt -r $AK_FINGERPRINT --armor --output $1 $2
    else
        exit 1
    fi
}

_ak_gpg_verify_clear_signature(){
    if [ ! -z $1 ] && [ -n "$1" ] && [ -f "$1" ]
    then
        fingerprint="$(cat $1 | _ak_gpg 2>&1 | grep RSA | awk '{print $5}')"
        if [ $? -ne 0 ]
        then
            _ak_log_error "Could not verify signature"
            exit 1
        fi
        _ak_log_debug "$1 signed with $fingerprint"
        cat $1 | _ak_gpg 2> /dev/null
    else
        _ak_log_error "Failed to verify detached signature $1 against $2"
        exit 1
    fi
}

_ak_gpg_verify_signature(){
    if [ ! -z $1 ] && [ -n "$1" ] && [ -f "$1" ] && [ ! -z $2 ] && [ -n "$2" ] && [ -f "$2" ] 
    then
        _ak_gpg --verify $1 $2 > /dev/null 2>&1
    else
        _ak_log_error "Failed to verify detached signature $1 against $2"
        exit 1
    fi
}

_ak_gpg_key_self_export(){
    if [ ! -z $1 ] && [ -n "$1" ]
    then
        _ak_gpg --armour --output $1 --export $AK_FINGERPRINT
    else
        exit 1
    fi
}

_ak_gpg_list_keys_plain(){
    _ak_gpg --list-keys
}

_ak_gpg_list_keys(){
    _ak_gpg --list-keys | grep '^ ' | awk '{print $1}'
}

_ak_gpg_list_keys_long(){
    _ak_gpg --list-keys | \
        grep -A 1 '^ \{6\}' | \
        tr $'\n' ' ' | \
        tr '\-\-' $'\n' | \
        sed -e 's/\[//g' | \
        awk '{print $1 " " $4}' | \
        sort | \
        uniq
}

_ak_gpg_list_secret_keys_plain(){
    _ak_gpg --list-secret-keys
}

_ak_gpg_list_secret_keys(){
    _ak_gpg --list-secret-keys | grep '^ ' | awk '{print $1}'
}

_ak_gpg_list_secret_keys_long(){
    _ak_gpg --list-secret-keys | \
        grep -A 1 '^ \{6\}' | \
        tr $'\n' ' ' | \
        tr '\-\-' $'\n' | \
        sed -e 's/\[//g' | \
        awk '{print $1 " " $4}' | \
        sort | \
        uniq
}

_ak_gpg_select_key(){
    select x in $(_ak_gpg_list_secret_keys | tr '\n' ' ')
    do
        if [ -n "$x" ]
        then
            _ak_log_info "$x was selected"
            _ak_settings_set "gpg.fingerprint" "$x"
            break
        else
            _ak_log_warning "You didn't select a key"
        fi
    done
}

_ak_gpg_delete_key(){
    select x in $(_ak_gpg_list_keys | tr '\n' ' ')
    do
        if [ -n "$x" ]
        then
            _ak_log_info "$x was selected"
            _ak_gpg --delete-keys $x
            if [ $? -ne 0 ]
            then
                _ak_log_error "Some error occured while removing $x"
            else
                _ak_log_info "Key $x was deleted"
            fi
            break
        else
            _ak_log_warning "You didn't select a key"
        fi
    done
}

_ak_gpg_delete_secret_key(){
    if [ ! -z $1 ]
    then
        x="$1"
        if [ -n "$x" ]
        then
            _ak_log_info "$x was selected"
            _ak_gpg --delete-secret-keys $x
            if [ $? -ne 0 ]
            then
                _ak_log_error "Some error occured while removing $x"
                exit 1
            else
                _ak_log_info "Key $x was deleted"
            fi
            exit
        else
            _ak_log_warning "You didn't select a key"
            exit 1
        fi
    fi
}