#!/bin/bash

if command -v pikaur &> /dev/null; then
    alias pacman="sudo pikaur"
elif command -v yay &> /dev/null; then
    alias pacman="yay"
else
    alias pacman="sudo pacman"
fi

alias _slides="$(which slides 2> /dev/null || echo "echo 'slides not installed'")"

CASCH_DIR="$HOME/.casch"
CASCH_MAP="$CASCH_DIR/.base-map.json"

function git-worked {
    author="$1"
    since="$2"

    if [[ "$author" == "" ]]; then
        author="Sage"
    fi
    if [[ "$since" == "" ]]; then
        since="1 year ago"
    fi

    cd "$HOME/git"
    local first=true
    for l in $(find -maxdepth 1 -mindepth 1 -type d | grep -v ' '); do
        cd ~/git
        cd $l
        if ! test -d .git; then
            continue
        fi
        local LIST="$(git rev-list --oneline --author="$author" --since="$since" HEAD)"
        if [[ "$(echo -E "$LIST" | wc -l)" > 1 ]]; then
            if ! $first; then
                echo
            fi
            first=false
            echo -E $l
            echo -E "$LIST"
        fi
    done
    cd ~/git
}

function touch-cache {
    local lastUpdate="$(date '+%s')"
    mkdir -p "$CASCH_DIR"
    test -f "$CASCH_MAP" || echo '{}' > "$CASCH_MAP"

    jq --arg cachedCommand "$1" --arg filename "$2" --arg lastUpdate "$lastUpdate" '.+={($cachedCommand): {$filename, $lastUpdate}}' "$CASCH_MAP" > "$CASCH_DIR/.tempbase.json"
    mv "$CASCH_DIR/.tempbase.json" "$CASCH_MAP"
}

function timer {
    for i in {0..$(($1-1))}; do
        echo $(($1-$i))
        sleep 1
        clear
    done
    cvlc --play-and-exit "$HOME/Downloads/bonk.ogg" &> /dev/null
}

function cache-is-older-than {
    local currentTime="$(date '+%s')"
    local lastUpdate="$(jq -r --arg cachedCommand "$1" '.[$cachedCommand].lastUpdate' "$CASCH_MAP")"
    local olderThanSec="$2"
    if [[ "$lastUpdate" == "null" ]]; then
        return 0
    fi
    (($currentTime-$olderThanSec>$lastUpdate))
}

function cache-run {
    local cacheFile="$CASCH_DIR/$@"
    if cache-is-older-than "$@" 300; then
        $@ | tee "$cacheFile"
        touch-cache "$@" "$cacheFile"
    else
        cat "$cacheFile"
    fi
}

alias cr='cache-run'

function roll {
    local count=1
    if [[ "$2" != "" ]]; then
        count="$2"
    fi
    local rolls="$(shuf -i 1-$1 -n $count)"
    echo "$rolls" | toilet
    for i in {1..$count}; do
        setsid cvlc --play-and-exit $HOME/Videos/roll.mp3 &> /dev/null
        sleep "0.0$(shuf -i 5-9 -n 1)"
    done
    if [[ "$count" != "1" ]]; then
        echo "Total: $(echo "$rolls" | paste -s -d+ - | bc)" | toilet
    fi
}

function arr {
    local json="["
    for var in "$@"
    do
        json="$json$(echo "$var" | jq -R),"
    done
    json=${json:0:-1}
    json="$json]"
    echo "$json" | jq --indent 0
}

alias d4='roll 4'
alias 4='roll 4'

alias d6='roll 6'
alias 6='roll 6'

alias d8='roll 8'
alias 8='roll 8'

alias d10='roll 10'
alias 10='roll 10'

alias d12='roll 12'
alias 12='roll 12'

alias d20='roll 20'
alias 20='roll 20'

alias dedup="awk '!seen_lines[$0]++'"
alias dedup-keep-last="tac | awk '!seen_lines[$0]++' | tac"

function helpdef {
    if [[ "$1" == "--help" ]] || [[ "$1" == "-h" ]]; then
        echo "$2"
        return 0
    fi
    return 1
}

function wait-for {
    while ! bash -c "$@"; do sleep 1; done
}

function slides() {
    OLD_PATH="$PATH"
    PATH="$HOME/.slides-bin:$PATH"
    _slides $@
    PATH="$OLD_PATH"
}

function suckto {
    local dest_branch="$(echo "$@" | sed 's/ /-/g')"
    changed_files="$(git status --porcelain=v1 2>/dev/null | wc -l)"
    git suck
    git switch -c "$dest_branch"
    if [[ "$changed_files" != "0" ]]; then
        git stash pop
    fi
}

function integrate {
    local from="$(realpath $1)"
    if [[ "$from" == "$f"* ]]; then
        echo "File is already in $f"
        return 1
    fi
    local to="${from/${HOME}/${f}}"
    local sec=3
    echo "mv '$from' '$to' in $sec seconds"
    sleep $sec
    mv -n "$from" "$to" || return 1
    cd $DOT_DIR || return 1
    ./copy.sh
    cd -
}

function ishelp {
    [[ "$1" == "help" ]] || [[ "$1" == "-h" ]] || [[ "$1" == "--help" ]]
}

function stv {
    local stash=0
    if ishelp $1; then
        echo "Show the diff for the given stash. Default to 0"
        return
    fi
    if [[ "${1:0:1}" == "^" ]]; then
        stash=${#1}
    elif [[ "$1" != "" ]]; then
        stash="$1"
    fi
    git stash show -p stash@{$stash}
}

function hearch {
    history 0 | sed 's/[0-9 ]*//' | grep "$@"
}

function ungrep {
    helpdef "$1" "grep -v's all arguments from the piped input" && return 0
    local output="$(cat)"
    for arg in "$@"; do
        output="$(echo "$output" | grep -v "$arg")"
    done
    echo "$output"
}

function pwgen {
    echo "$@ $(openssl rand -base64 64 | tr -d '012456789+/=\n')"
}

alias k='kubectl'

function kube-pod-name {
    local pods="$(kubectl get pods | grep "$1")"
    local selection="1"
    if [[ "$2" != "" ]]; then
        selection="$2"
    fi
    local pod="$(echo "$pods" | awk '{print $1}' | head -n $selection | tail -n 1)"
    echo "$pod"
}

function kubelog {
    kubectl logs -f "$(kube-pod-name $@)"
}

function kubetty {
    kubectl exec "$(kube-pod-name $@)" -i -t -- bash
}

function undelete {
    local filename="$1"
    if test -f "$filename"; then
        echo "File already exists!"
        exit 1
    fi

    # Get all commit hashes for this file
    # Presumably, the one that deleted it was the most recent one :D
    local hashes="$(git log --all --format=format:%H -- "$filename" | head -n 2)"
    if [[ "$(echo $hashes | wc -l)" != "2" ]]; then
        echo "Expected at least two commits relating to this file!"
        exit 1
    fi

    # Checkout the file from the commit before it was deleted
    local hash="$(echo $hashes | tail -n 1)"
    git checkout $hash -- "$filename"
}

alias j='journalctl -xefu'
alias hsearch='hearch'
alias d='docker'
alias uuid='uuidgen'
alias vin='curl -s "http://randomvin.com/getvin.php?type=real"'

alias diff='diff -u'

alias tmux="tmux attach || tmux"

alias caddyfile="sudo vim /etc/caddy/Caddyfile"
alias cf="sudo vim /etc/caddy/Caddyfile"

function v {
    if test -f "$1"; then
        vim "$1"
    else
        vim $1*
    fi
}

function download-channel {
  yt-dlp "$1" --format 'bestvideo[height=1080]+bestaudio/best' --download-archive archive.txt --output '%(uploader)s/%(upload_date)s.%(title)s.%(id)s.%(ext)s' --restrict-filenames --merge-output-format mkv --ignore-errors
}

function fin {
    find -iname "*$@*"
}

function scpace {
    scp -P 11275 $@
}

function gamp {
    git add * && git commit -am "$1" && git push
}

function gap {
    git add * && git commit -a && git push
}

function gd {
    git add * && git diff --cached --word-diff=porcelain
}

function wf {
    if [[ "$@" != "" ]]; then
        local fzf_args="-q $@"
    fi
    local wiki_dir="$HOME/wiki/"
    if [[ "$WIKI_DIR" != "" ]]; then
        wiki_dir="$WIKI_DIR"
    fi
    echo $wiki_dir/"$(rg --with-filename --no-heading . "$wiki_dir" | sed "s@$wiki_dir@@" | fzf -i $fzf_args -1 --preview="bat $wiki_dir/\$(echo {} | sed 's/:.*//')" | sed 's/:.*//')"
}

function ws {
    local filename="$(wf $@)"
    if [[ "$filename" != "" ]]; then
        vim $filename
    fi
}

function ww {
    local wiki_dir="$HOME/wiki/"
    if [[ "$WIKI_DIR" != "" ]]; then
        wiki_dir="$WIKI_DIR"
    fi
    ws $(rg --no-line-number --no-filename . "$wiki_dir" | sed 's/[^a-zA-Z0-9]\+/\n/g' | grep -v "^$" | sort -f | uniq -ci | sort -hr | fzf -i | cut -c 9-)
}

if command -v bat &> /dev/null; then
    alias cat="bat -p"
fi
export FZF_DEFAULT_COMMAND='fd --type f'
alias fzf="fzf --preview 'bat --style=numbers --color=always {}'"

function vo {
    if [[ "$1" == "" ]]; then
        local f="$(fzf --preview "bat --style=numbers --color=always {}")"
        if [[ "$f" != "" ]]; then
            print -s "vim $f"
            vim $f
        fi
    else
        local f="$(fzf -1 -q $@ | head -n 1)"
        if [[ "$f" != "" ]]; then
            print -s "vim $f"
            vim $f
        fi
    fi
    echo $f
}

alias yt='yt-dlp'
function y {
    cd ~/.ytdl; yt-dlp $@; cd -
}

# Mkdir should remind you to use git
alias mkdir="echo 'Maybe use git init if this is a new project' && mkdir"

# Use `al` to view and edit aliases
alias al="vim ~/.shell_aliases && source ~/.shell_aliases && pushdot"

# Sudo commands will turn red
alias sudo='echo -e "\e[1;31m" && sudo'

alias clip="xclip -selection clipboard"

alias cim="vim"

# Use `vimc` to edit ~/.vimrc
alias vimc="vim ~/.vimrc && pushdot"
alias cimc="vim ~/.vimrc && pushdot"

# Resume session
alias vims="vim -S *.vims"

# Use `zz` to edit ~/.zshrc
alias zz='vim ~/.zshrc && source ~/.zshrc && pushdot'
alias termrc='vim ~/.config/xfce4/terminal/terminalrc'

# Use `grepr` for a recursive, case-insensitive, and filtered grep
# alias grepr="grep -RInsi --color=auto --exclude-dir=.git --exclude=tags"
# alias grepr='grep -RInsi --color=auto --exclude-dir=.git --exclude-dir=banana_pi_kernel --exclude-dir={bpi_build_scripts, storm_dox, sam_dox} --exclude=tags --exclude=\*.{ko, o}'
alias grepr='grep -RIns --color=auto --exclude-dir=.git --exclude-dir=venv --exclude-dir=node_modules --exclude=tags --exclude-dir=build --exclude-dir=.idea'
alias grepi='grepr -i'

alias apt="sudo apt"
alias apt-get="sudo apt-get"
alias dnf="sudo dnf"
alias eject="sudo eject"
alias dpkg="sudo dpkg"
alias dpi="sudo dpkg -i"
alias systemctl="sudo systemctl"

alias python="python3"
alias py="python3"

alias g="git"

# Use `grubdate` to update grub
alias grubdate="sudo update-grub"

# Use `open` after `grepr` to vim a file with grep text matching $1
alias open=_open
alias open2=_open2

# `pp` and `pwoeroff` -> `poweroff`
alias pp=poweroff
alias pwoeroff=poweroff

# Use `ll` to get a detailed list of files, sorted by size
alias ll='ls --color=auto -FlrSh -w 80'
alias ls='ls --color=auto -F -w 80'

# Using du automatically finds the total
alias du='du -sh'

alias tags='ctags --exclude=node_modules -f newtags -R . && mv newtags tags'

if [[ "$@" != "" ]]; then
    $@
fi