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

golang_src_git_repo_url="https://github.com/golang/go"
yggdrasil_src_git_repo_url="https://github.com/yggdrasil-network/yggdrasil-go"

function _ak_go_lang_check(){
    go_bin_location="$(which go)"
    if [ -n "${go_bin_location}" ]
    then
        go_version="$(${go_bin_location} version | cut -d ' ' -f 3 | sed 's/go//')"
        go_major_version="$(echo -n ${go_version}|cut -d '.' -f 1)"
        go_minor_version="$(echo -n ${go_version}|cut -d '.' -f 2)"
        go_patch_version="$(echo -n ${go_version}|cut -d '.' -f 3)"
        if [ ${go_major_version} -eq 1 ] && [ ${go_minor_version} -ge 22 ]
        then
            _ak_log_info "The right version of Golang is installed"
        else
            _ak_log_error "Needs version >= 1.22 but got ${go_version}"
            exit 1
        fi
    else
        _ak_log_error "Golang not found in your system. Trying to download..."
        _ak_go_lang_install
    fi
}

function _ak_yggdrasil_check_availability(){
    declare -a yggdrasil_bins=("yggdrasil" "yggdrasilctl")
    for ybin in "${yggdrasil_bins[@]}"
    do
        which $ybin > /dev/null 2>&1
        if [ $? -ne 0 ]
        then
            _ak_log_error "$ybin not found"
            exit 1
        else
            _ak_log_info "$ybin found"
        fi
    done
}

function _ak_go_lang_install(){
    go_download_url="https://go.dev/dl/go1.24.0.linux-amd64.tar.gz"
    curl "$(curl "${go_download_url}" | sed -e 's/^.*="//g; s/".*$//g')" > go.tar.gz
    rm -rf ./go && tar -C . -xzf go.tar.gz
    export PATH=$PATH:$(pwd)/go/bin
    go version > /dev/null 2>&1
    if [ $? -ne 0 ]
    then
        _ak_log_error "Something went wrong while installing Go-lang"
        exit 1
    fi
}

function _ak_yggdrasil_install(){
    # _ak_cargo_rust_check_install
    git clone ${yggdrasil_src_git_repo_url}
    yggdrasil_install_script="./build"
    cd yggdrasil-go
    sh ${yggdrasil_install_script}
    if [ $? -ne 0 ]
    then
        _ak_log_error "Failed to compile yggdrasil"
        exit 1
    fi
    cd ..
    # sudo cp yggdrasil/cjdroute /usr/bin/cjdroute
    # sudo cp yggdrasil/target/release/makekeys /usr/bin/makekeys
    # sudo cp yggdrasil/target/release/mkpasswd /usr/bin/mkpasswd
    # sudo cp yggdrasil/target/release/privatetopublic /usr/bin/privatetopublic
    # sudo cp yggdrasil/target/release/publictoip6 /usr/bin/publictoip6
    # sudo cp yggdrasil/target/release/randombytes /usr/bin/randombytes
    # sudo cp yggdrasil/target/release/sybilsim /usr/bin/sybilsim
    # ln -s "$(realpath yggdrasil/tools/dumpLinks)" ${HOME}/.arching-kaos/bin/dumpLinks
    # ln -s "$(realpath yggdrasil/tools/cexec)" ${HOME}/.arching-kaos/bin/yggdrasil-cexec
    # ln -s "$(realpath yggdrasil/tools/peerStats)" ${HOME}/.arching-kaos/bin/peerStats
    which systemctl 2> /dev/null 1>&2
    if [ $? -ne 0 ]
    then
        _ak_log_error "Systemctl not found... TODO"
    else
        echo
        # sudo cp yggdrasil/contrib/systemd/yggdrasil.service /etc/systemd/system/yggdrasil.service
        # sudo cp yggdrasil/contrib/systemd/yggdrasil-resume.service /etc/systemd/system/yggdrasil-resume.service
        # sudo systemctl enable --now yggdrasil.service
    fi
}

# function _ak_yggdrasil_read_peers_to_vars_with_jq(){
#     totalpeers="$(jq '. | length' < $peersfile)"
#     number="0"
#     interface="0"
#     while [ $number -lt $totalpeers ]
#     do
#         address="$(jq -r '.['$number'].address' < $peersfile)"
#         login="$(jq -r '.['$number'].login' < $peersfile)"
#         password="$(jq -r '.['$number'].password' < $peersfile)"
#         publicKey="$(jq -r '.['$number'].publicKey' < $peersfile)"
#         peerName="$(jq -r '.['$number'].peerName' < $peersfile)"
#         if [ $(echo $address | grep '\[') ]
#         then
#             interface="1"
#         else
#             interface="0"
#         fi
#         $yggdrasiltoolspath/cexec 'UDPInterface_beginConnection("'$publicKey'", "'$address'", "'$peerName'", "'$password'", "'$login'", '$interface')'
#         number="$(( $number + 1 ))"
#     done
# }
#
# function _ak_yggdrasil_read_peers_to_vars_natively(){
#     number=-1
#     cat $peersfile | tr -d $'\n' | sed -e 's/]$/\n/g' | tr -d ' ' | sed -e 's/"//g; s/,/,\n/g; s/}//g; s/,//g' | while read line
#     do
#         if [ $(echo "$line" | grep '{') ]
#         then
#             number=$(($number + 1))
#             if [ $number -ne 0 ]
#             then
#                 printf '\n' >> peerfile
#             fi
#         fi
#         if [ $(echo "$line" | grep 'address') ]
#         then
#             printf '%s ' "$(echo -n $line | cut -d ':' -f 2-)" >> peerfile
#         fi
#         if [ $(echo "$line" | grep 'password') ]
#         then
#             printf '%s ' "$(echo -n $line | cut -d ':' -f 2-)" >> peerfile
#         fi
#         if [ $(echo "$line" | grep 'publicKey') ]
#         then
#             printf '%s ' "$(echo -n $line | cut -d ':' -f 2-)" >> peerfile
#         fi
#         if [ $(echo "$line" | grep 'login') ]
#         then
#             printf '%s ' "$(echo -n $line | cut -d ':' -f 2-)" >> peerfile
#         fi
#         if [ $(echo "$line" | grep 'peerName') ]
#         then
#             printf '%s ' "$(echo -n $line | cut -d ':' -f 2-)" >> peerfile
#         fi
#     done
#     printf '\n' >> peerfile
#     cat peerfile | while read address login password publicKey peerName
#     do
#         if [ $(echo $address | grep '\[') ]
#         then
#             interface="1"
#         else
#             interface="0"
#         fi
#         $yggdrasiltoolspath/cexec 'UDPInterface_beginConnection("'$publicKey'", "'$address'", "'$peerName'", "'$password'", "'$login'", '$interface')'
#     done
#     rm peerfile
# }

function _ak_yggdrasil_connect_peers(){
    _ak_network_yggdrasil_connect
    exit $?
    #
    # Peers file have to look like this:
    #
    # [
    #   {
    #     "address": "<IPv4|IPv6>:<port>",
    #     "login": "<login-name>",
    #     "password": "<password...>",
    #     "publicKey": "<publickey with .k suffix>",
    #     "peerName": "<peername>"
    #   },
    #   { ... } <- more peers
    # ]
    #
    # You can have both IPv4 and IPv6 peers on the same file
    #
    # Assumes there is ~/yggdrasil/tools/cexec in place, change it below
    #
    if [ ! -z $1 ] && [ -n "$1" ] && [ -f $1 ]
    then
        peersfile="$1"
    else
        echo "Usage: $(basename $0) <json-peer-list-file>"
        exit 1
    fi
    if command -v jq
    then
        _ak_yggdrasil_read_peers_to_vars_with_jq
    else
        _ak_yggdrasil_read_peers_to_vars_natively
    fi
}

function _ak_yggdrasil_get_ip(){
    which ip > /dev/null 2>&1
    if [ $? -ne 0 ]
    then
        _ak_log_error "You need ip tool installed"
        exit 2
    fi
    ip a | \
        grep 'inet6 *[2|3][0-9a-f]\{1,3\}:' | \
        awk '{print $2}' | \
        cut -d'/' -f1
}

_ak_log_debug "_ak_yggdrasil loaded $(caller)"