#
# ~/.bashrc :: by frode klevstul
#

# if not running interactively, don't do anything
[[ $- != *i* ]] && return


# ---
# shell integrations
# ---

# https://github.com/gsamokovarov/jump
eval "$(jump shell --bind=j)"

# https://github.com/ajeetdsouza/zoxide
eval "$(zoxide init bash)"


# ---
# prompt
# ---

# https://bash-prompt-generator.org/
PS1='\[⚙\][\D{%y%m%d%H%M}|\u@\h|\w]\$ '

# change the window title of x terminals
case ${TERM} in
    xterm*|rxvt*|Eterm*|aterm|kterm|gnome*|interix|konsole*)
        PROMPT_COMMAND='echo -ne "\033]0;${USER}@${HOSTNAME%%.*}:${PWD/#$HOME/\~}\007"'
        ;;
    screen*)
        PROMPT_COMMAND='echo -ne "\033_${USER}@${HOSTNAME%%.*}:${PWD/#$HOME/\~}\033\\"'
        ;;
esac


# ---
# environment variables
# ---
# see `dots/environment/environment`


# ---
# aliases : system
# ---

alias cp="cp -i"                            # confirm before overwriting something
alias df='df -h'                            # human-readable sizes
alias du="du --summarize --human-readable"
alias dus="du --summarize --human-readable * | sort -h"
alias grep='grep --color=auto'
alias ls='ls --color=auto'
alias tree="tree --du -h"


# ---
# aliases : files & disk
# ---

alias biggestfiles="find ~ -type f -exec du -h {} + 2>/dev/null | sort -hr | head -n 20"
alias diskusage="ncdu -x"
alias dragon="dragon-drop --and-exit --all --print-path"
alias extract="extract.sh"
alias sizeInBytes="stat -c %s"
alias zipr='zip -r "$1" . -x "$1"'


# ---
# aliases : trash
# ---

alias tp="tp.sh"
alias tp-empty="trash-put /dev/null; trash-empty; gio trash --empty"   # fixed: was recursive
alias tp-list="tree ~/.local/share/Trash/"
alias tp-restore="trash-restore"


# ---
# aliases : networking
# ---

alias ipadr='ip -br a'
alias ipify='http https://api.ipify.org?format=json'
alias journal='journalctl --since "1 hour ago"'
alias ssh="ssh -v"
alias ssh_weba_r="ssh -t root@weba -p 1808 'export TERM=xterm; cd /tmp; bash -l'"
alias ssh_weba_u="ssh -t usr@weba -p 1808 'export TERM=xterm; cd /tmp; bash -l'"


# ---
# aliases : applications
# ---

alias azurevpnclient="/opt/microsoft/microsoft-azurevpnclient/microsoft-azurevpnclient"
alias ct="sudo ct"
alias decrypt="gpg --decrypt"
alias dragon="dragon-drop --and-exit --all --print-path"
alias encrypt="gpg --encrypt --sign --recipient frode@klevstul.com"
alias gparted="sudo gparted"
alias ipcam="ffplay rtsp://192.168.31.220:554/1"
alias keyringreset="trash-put /home/poq/.local/share/keyrings/*.keyrings"
alias neofetch='fastfetch'
alias quantumfix="pw-metadata -n settings 0 clock.force-quantum 1024"


# ---
# aliases : hyprland
# ---

alias hyprRld="hyprctl reload"
alias hyprUpd="sudo ct d h && hyprRld"


# ---
# aliases : app images
# ---

alias pgmodeler="/home/poq/syncDir/swas/portableApps/pgmodeler_plus-1*"
alias pgmodeler2="/home/poq/syncDir/swas/portableApps/pgmodeler_plus-2*"


# ---
# aliases : bash
# ---

alias sb="unalias -a; source ~/.bashrc"
alias sbr="unalias -a; source /home/poq/syncDir/repos/git/gi.op.fo/lnx-arch/dots/bash/.bashrc"


# ---
# aliases : nas mounting
# ---

alias nas-mount="nas mount 192.168.31.77"
alias nas-umount="nas umount"


# ---
# functions : networking
# ---

myip() {
    wget http://ipinfo.io/ip -qO -
    echo
}

nmrestart() {
    systemctl restart NetworkManager
    systemctl status NetworkManager
}


# ---
# functions : file managers
# ---

# lf (change directory on quit)
lf() {
    local tmp
    tmp=$(mktemp)
    command lf -last-dir-path="$tmp" "$@"
    if [[ -f "$tmp" ]]; then
        local dir
        dir=$(cat "$tmp")
        rm -f "$tmp"
        if [[ -d "$dir" && "$dir" != "$(pwd)" ]]; then
            cd "$dir"
        fi
    fi
}

# superfile (change directory on quit)
spf() {
    local SPF_LAST_DIR="${XDG_STATE_HOME:-$HOME/.local/state}/superfile/lastdir"
    command spf "$@"
    if [[ -f "$SPF_LAST_DIR" ]]; then
        source "$SPF_LAST_DIR"
        rm -f "$SPF_LAST_DIR"
    fi
}


# ---
# functions : nas
# ---

nas() {
    if [[ ! -e "/mnt/nas" ]]; then
        sudo mkdir -p "/mnt/nas" "/mnt/nas-fam"
    elif [[ ! -d "/mnt/nas" ]] || [[ ! -d "/mnt/nas-fam" ]]; then
        echo "'/mnt/nas' and/or '/mnt/nas-fam' exist, but is not a directory" >&2
        return 1
    fi

    case "$1" in
        umount|unmount)
            echo "umount /mnt/nas & /mnt/nas-fam"
            sudo umount -l /mnt/nas
            sudo umount -l /mnt/nas-fam
            ;;
        mount)
            if [[ -z "$2" ]]; then
                echo "missing ip address. try: 'nas mount <ip>'" >&2
                return 1
            fi
            echo "mount /mnt/nas & /mnt/nas-fam"
            local creds=/home/poq/syncDir/secrets/nas/lillesorteboks.txt
            local opts="credentials=${creds},iocharset=utf8,noperm"
            sudo mount -t cifs -o "$opts" "//$2/fro" /mnt/nas
            sudo mount -t cifs -o "$opts" "//$2/fam" /mnt/nas-fam
            tree -L 2 /mnt/nas
            tree -L 2 /mnt/nas-fam
            ;;
        *)
            echo "usage: nas {mount <ip>|umount}" >&2
            return 1
            ;;
    esac
}


# ---
# functions : multimedia
# ---

# https://itsfoss.com/compress-pdf-linux/
pdfCompress() {
    gs -sDEVICE=pdfwrite -dCompatibilityLevel=1.5 -dPDFSETTINGS=/ebook \
        -dNOPAUSE -dQUIET -dBATCH -sOutputFile="$1.compressed.pdf" "$1"
}

# https://stackoverflow.com/questions/8933053/check-duration-of-audio-files-on-the-command-line
lengthInSeconds() {
    ffprobe -show_entries format=duration -of default=noprint_wrappers=1:nokey=1 "$1" 2>/dev/null
}


# ---
# functions : misc
# ---

generate_password() {
    local length=30
    local chars='A-Za-z0-9!@#$%^&*()_+[]{}|;:,.<>?'
    tr -dc "$chars" < /dev/urandom | head -c "$length"
    echo
}

randoms() {
    echo "----------"

    local ranwrd1 ranwrd2 rancmd randnum randalp
    ranwrd1=$(shuf -n 1 /usr/share/dict/cracklib-small)
    ranwrd1="${ranwrd1//[^[:alpha:]]/}"
    ranwrd2=$(shuf -n 1 /usr/share/dict/cracklib-small)
    ranwrd2="${ranwrd2//[^[:alpha:]]/}"
    rancmd=$(compgen -ac | shuf -n 1)
    randnum=$(( 1000 + SRANDOM % 9000 ))
    randalp=$(tr -dc 'a-zA-Z0-9' < /dev/urandom | head -c 10)

    echo "w1: ${ranwrd1} | w2: ${ranwrd2} | c: ${rancmd} | n: ${randnum} | a: ${randalp}"
    echo "s0: ${randnum} ${ranwrd1} ${ranwrd2} ${rancmd} ${randalp}"
    echo "s1: ${randnum}_${ranwrd1}_${ranwrd2}_${rancmd}_${randalp}"
    echo "s2: ${randnum}${ranwrd1}${ranwrd2}${rancmd//[^[:alpha:]]/}${randalp}"
    echo "s3: $(generate_password)"

    echo "----------"
}

quick_hours() {
    local location=$1
    local balance=$2
    local worked=$3
    local target=450  # 7:30 in minutes

    local hours minutes worked_minutes
    hours="${worked%%:*}"
    minutes="${worked##*:}"
    worked_minutes=$(( 10#$hours * 60 + 10#$minutes ))

    local new_balance=$(( balance + worked_minutes - target ))
    echo "[@${location} ${new_balance}]"
}


# ---
# functions : searching
# ---

# find a file (faf)
faf() {
    local path="${2:-.}"
    find "$path" -type f -iname "$1" 2>/dev/null
}

# find in file (fif)
# https://stackoverflow.com/questions/16956810/find-all-files-containing-a-specific-text-string-on-linux
fif() {
    local path="${2:-.}"
    grep -rnw "$path" -e "$1" 2>/dev/null
}


# ---
# functions : rotate / encode
# ---

decimal_to_base36() {
    local BASE36=($(echo {0..9} {A..Z}))
    for i in $(bc <<< "obase=36; $1"); do
        echo -n "${BASE36[$(( 10#$i ))]}"
    done
    echo
}

decimal_to_base36_wrap() {
    decimal_to_base36 $(( $1 % 36 ))
}

rot() {
    local shift=$1
    local text=$2
    local alpha=abcdefghijklmnopqrstuvwxyz

    if [[ -z $shift || -z $text ]]; then
        echo "usage: rot <shift> <text>"
        return 1
    fi

    local n=$(( (shift % 26 + 26) % 26 ))
    local rotated="${alpha:n}${alpha:0:n}"
    echo "$text" | tr "a-z" "$rotated"
}

rotl() {
    local input=$1
    if [[ -z "$input" ]]; then return 1; fi

    local size=${#input}
    if (( size > 25 && size < 51 )); then    # fixed: was string comparison
        size=$(( size - 25 ))
    fi

    if [[ -n $2 ]]; then
        rot "$size" "$input"
    else
        { echo "rot +$size: "; rot "$size" "$input"; } | tr "\n" " "
        echo
        { echo "rot -$size: "; rot "-$size" "$input"; } | tr "\n" " "
        echo
    fi
}

rote() {
    local input="${1//./}"
    _rote_encode "$input"
}

_rote_encode() {
    local input=$1
    if [[ -z "$input" ]]; then return 1; fi

    local year month day
    year=$(decimal_to_base36_wrap "$(date +%y)")
    month=$(decimal_to_base36 "$(date +%m)")
    day=$(decimal_to_base36 "$(date +%d)")

    local datestamp
    datestamp=$(echo "${year}${month}${day}_" | tr '[A-Z]' '[a-z]')

    local rotl_result
    rotl_result=$(rotl "$input" 0)

    echo "${datestamp}${rotl_result}@reduxmail.com"
}

drote() {
    local email="$1"
    local local_part="${email%@reduxmail.com}"
    local ds="${local_part%%_*}"
    local encoded="${local_part#*_}"

    _b36_to_dec() {
        local c="${1,,}"
        if [[ "$c" =~ [0-9] ]]; then
            echo "$c"
        else
            printf "%d" $(( $(printf '%d' "'$c") - 87 ))
        fi
    }

    local yy mm dd
    yy=$(_b36_to_dec "${ds:0:1}")
    mm=$(_b36_to_dec "${ds:1:1}")
    dd=$(_b36_to_dec "${ds:2:1}")
    local yymmdd
    yymmdd=$(printf "%02d%02d%02d" "$yy" "$mm" "$dd")

    local size=${#encoded}
    if (( size > 25 && size < 51 )); then
        size=$(( size - 25 ))
    fi
    local shift=$(( size % 26 ))

    local decoded="" i c ascii rotated
    for (( i = 0; i < ${#encoded}; i++ )); do
        c="${encoded:$i:1}"
        ascii=$(printf '%d' "'$c")
        if (( ascii >= 97 && ascii <= 122 )); then
            rotated=$(( (ascii - 97 - shift + 26) % 26 + 97 ))
            decoded+=$(printf "\\$(printf '%03o' "$rotated")")
        elif (( ascii >= 65 && ascii <= 90 )); then
            rotated=$(( (ascii - 65 - shift + 26) % 26 + 65 ))
            decoded+=$(printf "\\$(printf '%03o' "$rotated")")
        else
            decoded+="$c"
        fi
    done

    echo "$yymmdd: $decoded"
}


# ---
# functions : web / jongleur
# ---

_jongleur_base=/home/poq/syncDir/repos/git/gi.op.fo
_jongleur_deploy_user=usr@178.156.192.201

jongleur-activate() {
    cd /home/poq/syncDir/repos/git/gitlab.com/jongleur/src
    source venv/bin/activate
}

_jongleur_site() {
    local site=$1
    local action=$2
    local base="$_jongleur_base/${site}"

    case "$action" in
        build)
            jongleur-activate
            "${base}/jongleur/run.sh"
            deactivate
            cd /home/poq/syncDir/0_downloads
            ;;
        build-all)
            jongleur-activate
            "${base}/jongleur/runAll.sh"
            deactivate
            cd /home/poq/syncDir/0_downloads
            ;;
        deploy)
            rsync -v -a --progress --stats --delete-delay \
                -e 'ssh -p 1808' \
                "${base}/jongleur/html_export/" \
                "${_jongleur_deploy_user}:/var/www/${site}/jongleur/"
            ;;
        *)
            echo "usage: <site>-{build|build-all|deploy}" >&2
            return 1
            ;;
    esac
}

# site shortcuts
for _site in ajp.fm antijanteboka.com antijantemiriam.com billgoats.com curious.art curiouscreators.com frodr.com klevstul.com; do
    eval "${_site//./_}-build()     { _jongleur_site '${_site}' build; }"
    eval "${_site//./_}-build-all() { _jongleur_site '${_site}' build-all; }"
    eval "alias ${_site}-build=\"${_site//./_}-build\""
    eval "alias ${_site}-build-all=\"${_site//./_}-build-all\""
    eval "alias ${_site}-deploy=\"rsync -v -a --progress --stats --delete-delay -e 'ssh -p 1808' ${_jongleur_base}/${_site}/jongleur/html_export/ ${_jongleur_deploy_user}:/var/www/${_site}/jongleur/\""
done
unset _site

# special case: klevstul.com deploys to weba
alias klevstul.com-deploy="rsync -v -a --progress --stats --delete-delay -e 'ssh -p 1808' ${_jongleur_base}/klevstul.com/jongleur/html_export/ usr@weba:/var/www/klevstul.com/jongleur/"

# misc website deploys
alias 00101111.xyz-deploy="rsync -v -a --progress --stats --delete-delay -e 'ssh -p 1808' /home/poq/syncDir/repos/git/gi.op.fo/00101111.xyz/www/ usr@weba:/var/www/00101111.xyz/"
alias factor.red-deploy="rsync -v -a --progress --stats --delete-delay -e 'ssh -p 1808' /home/poq/syncDir/repos/git/gi.op.fo/mini-websites/factor.red/ usr@weba:/var/www/factor.red/"
alias op.fo-deploy="rsync -v -a --progress --stats --delete-delay -e 'ssh -p 1808' /home/poq/syncDir/repos/git/gi.op.fo/mini-websites/op.fo/ usr@weba:/var/www/op.fo/"
alias wa.fo-deploy="rsync -v -a --progress --stats --delete-delay -e 'ssh -p 1808' /home/poq/syncDir/repos/git/gi.op.fo/mini-websites/wa.fo/ usr@weba:/var/www/wa.fo/"


# ---
# functions : ajp / podigy / jeton
# ---

podigy() {
    cd /home/poq/syncDir/repos/git/gi.op.fo/podigy/src
    source venv/bin/activate
    python archi.py -s /home/poq/syncDir/repos/git/gi.op.fo/fiodb/db/podigy/sites
    deactivate
}

jeton() {
    cd /home/poq/syncDir/repos/git/gi.op.fo/jeton/src/
    source venv/bin/activate
    python archi.py -s /home/poq/syncDir/repos/git/gi.op.fo/fiodb/db/jeton/in/sites -r "$1"
    deactivate
}

jcssbuilder() {
    cd /home/poq/syncDir/repos/git/gi.op.fo/jCssBuilder/src
    source venv/bin/activate
    python /home/poq/syncDir/repos/git/gi.op.fo/jCssBuilder/src/archi.py
    deactivate
}
