#!/bin/bash

# TODO: make sure all arguments are safe
# TODO: there was something else, but i very badly forgot what it was!

readonly HTTP_BASE="https://nebula.ed1.club/stuff/ijo"
readonly SSH_BASE="nebula@ed1.club"
readonly REMOTE_BASE="stuff/ijo"

private=false
unlisted=false
delete=false
list=false
copy=false
paste=false

OPTIND=1
while getopts ":dhlpucv" opt; do
    case $opt in
        u)
            unlisted=true
            ;;
        p)
            private=true
            ;;
        d)
            delete=true
            ;;
        l)
            list=true
            ;;
        c)
            copy=true
            ;;
        v)
            paste=true
            ;;
        h)
            echo "-p: Act on a private file. (If not specified, on a public file.)"
            echo "-u: Act on an unlisted file. (If not specified, on a listed file.)"
            echo "-d: Delete the stated file. (If not specified, upload a file."
            echo "-l: List all files."
            echo "-v: Upload contents of the clipboard."
            echo "-c: Copy uploaded file URL."
            exit 0
            ;;
        \?)
            echo "Invalid option: -$OPTARG" >&2
            exit 1
            ;;
    esac
done

i="$OPTIND"

if [ -n "${!i}" ] && [ "$list" = true ]; then
    >&2 echo "Didn't expect filename."
    exit 1
fi

if [ -z "${!i}" ] && [ "$list" = false ]; then
    >&2 echo "Expected filename."
    exit 1
fi

if [ "$private" = true ]; then
    if [ "$unlisted" = true ]; then sshdir="private/unlisted"
    else sshdir="private"; fi
else
    if [ "$unlisted" = true ]; then sshdir="unlisted"
    else sshdir=""; fi
fi

# TODO: this one is kind of suboptimal (maybe rsync can list files in a good way?)
# if not, we can at least delegate _just the find command_ to ssh
if [ "$list" = true ]; then
    ssh -t "$SSH_BASE" << EOF

find "$REMOTE_BASE" -type f -printf '%Ts\t%p\n' | sort -n | cut -f2 |
    while read -r -d $'\n' x; do
        if [ -n "\$x" ]; then
            date="\$(stat -c '%Y' "\$x")"
            datefmt="\$(date -d "@\$date" +'%F %T')"
            file="\${x#"$REMOTE_BASE"}"

            private=false
            [[ "\$file" == */private/* ]] && private=true

            unlisted=false
            [[ "\$file" == */unlisted/* ]] && unlisted=true

            filename=\${file#"/private/"}
            filename=\${filename#"/stuff/"}
            filename=\${filename#"unlisted/"}

            if [ "\$private" = true ]; then
                printf "\033[31m[Private"
            else
                printf "\033[32m[Public"
            fi
            if [ "\$unlisted" = true ]; then
                printf -- "-\033[22mUnlisted"
            fi
            printf "\033[22m] "

            printf "\033[1m"
            printf "\$filename"
            printf '\r\033[40C '
            printf "\033[22m"
            printf "\$datefmt"
            printf "   "
            printf "\033[2m"
            printf "$HTTP_BASE\$file"
            printf "\033[0m"
            printf "\n"
        fi
    done

EOF
    exit 0
fi

unset temp_file

if [ "$paste" = true ]; then
    filename="$(mktemp)"
    temp_file="$filename"
    targetname="${!i}"

    if [ -n "$WAYLAND_DISPLAY" ]; then
        wl-paste > "$filename"
    else
        xclip -sel clip -out > "$filename"
    fi
else
    filename="${!i}"; (( i++ ))

    if [ -z "${!i}" ]; then
        targetname="$(basename "$filename")"
    else
        targetname="${!i}"
        settargetname=true
    fi
fi

function print_status {
    if [ "$private" = true ]; then
        printf "\033[31;1m[Private"
    else
        printf "\033[32;1m[Public"
    fi

    if [ "$unlisted" = true ]; then
        printf -- "-\033[22;2mUnlisted"
    fi

    printf "\033[22;1m]"
    printf "\033[0m "
}

target_path="$sshdir$targetname"
if [ "$delete" = true ]; then
    # TODO: this is kind of very dangerous!!!
    ssh "$SSH_BASE" "rm -i -- \"$REMOTE_BASE/$target_path\""
    # TODO
    if [ "$?" = 1 ]; then
        print_status
        printf "\033[31mThat file doesn't exist!"
    else
        print_status
        printf "\033[31m"
        printf "Deleted"
    fi
else
    printf "\033[2m" # dim rsync progress to increase contrast of later lines
    # TODO: convert these into absolute paths! safety and whatnot!
    # dirname "$target_path"
    ssh "$SSH_BASE" mkdir -p "$REMOTE_BASE/$(dirname "$target_path")"
    rsync -sav "$filename" --info=progress2 --chmod=644 "$SSH_BASE:$REMOTE_BASE/$target_path"
    printf "\033[0m"
    print_status
    printf "\033[36m"
    printf "Uploaded"
fi

if [ -z "$temp_file" ]; then
    printf " \033[1m%s\033[22m" "$(basename "$filename")"
fi

if [ "$settargetname" = true ]; then
    printf " as "
    printf "\033[1m"
    printf "%s" "$(basename "$targetname")"
    printf "\033[22m"
fi

printf ".\033[0m\n"

http_path="$(echo "$HTTP_BASE/$target_path" | sed 's/ /%20/g')"

if [ "$copy" = true ]; then
    if [ -n "$WAYLAND_DISPLAY" ]; then
        echo -n "$http_path" | wl-copy
    else
        echo -n "$http_path" | xclip -sel clip
    fi
fi

# TODO: better url escaping!
echo "$http_path"

# Cleanup
printf "\033[0m"

if [ -n "$temp_file" ]; then
    rm -- "$temp_file"
fi
