#!/bin/bash
set -euo pipefail
# @TODO long-term, turn this simple bash script into more complex Python Click project

SKANSIBLE_SCRIPT_PATH=$(dirname "$0")

export ANSIBLE_FORCE_COLOR=True
SKANSIBLE_STAGE=0
ANSIBLE_VERBOSITY=0
SKANSIBLE_UNITTEST=False
SKANSIBLE_MODE=prod

if [[ "$1" == "version" ]]; then
    echo "26.07"
fi

if [[ "$1" == "show-defaults" ]]; then
    source "${SKANSIBLE_SCRIPT_PATH}/.env/bin/activate"
    printf "Private SSH keys available throufh SSH agent: |\n%s\n" "$(ssh-add -l)"
fi

if [[ "$1" == "start-agent" ]]; then
    source "${SKANSIBLE_SCRIPT_PATH}/.env/bin/activate"
    eval "$(ssh-agent -s)"
fi

if [[ "$1" == "list-agent" ]]; then
    source "${SKANSIBLE_SCRIPT_PATH}/.env/bin/activate"
    ssh-add -l
fi

if [[ "$1" == "populate-agent" ]]; then
    shift 1

    source "${SKANSIBLE_SCRIPT_PATH}/.env/bin/activate"
    
    if [[ "$1" == "all" ]]; then
        for SKANSIBLE_SSH_KEY in ~/.ssh/*; do
            case $SKANSIBLE_SSH_KEY in
                *.pub);;
                *.old);;
                *.bak);;
                */config);;
                */authorized_keys);;
                *_hosts);;
                */agent);;
                *) ssh-add "${SKANSIBLE_SSH_KEY}";;
            esac
        done
    elif [[ "$1" == "staging" ]]; then
        SKANSIBLE_SSH_KEY_COLLECTION=(~/.ssh/ed25519\@staging ~/.ssh/ecdsa\@staging ~/.ssh/ed25519-37851076-sk\@staging ~/.ssh/ecdsa-37851076-sk\@staging)
        shift 1
    elif [[ "$1" == "prod" ]]; then
        SKANSIBLE_SSH_KEY_COLLECTION=(~/.ssh/ed25519\@staging ~/.ssh/ecdsa\@staging ~/.ssh/ed25519-37851076-sk\@staging ~/.ssh/ecdsa-37851076-sk\@staging)
        shift 1
    elif [[ -n "$1" ]]; then
        # @TODO improve by adding fuzzy querying or file finding pror
        ssh-add "$1"
        exit 0
    fi

    for key in "${SKANSIBLE_SSH_KEY_COLLECTION[@]}"; do
        ssh-add "$key"
    done
    
    exit 0
fi

if [[ "$1" == "init" ]]; then
    shift 1

    source "${SKANSIBLE_SCRIPT_PATH}/.env/bin/activate"

    if [[ "$1" == "vps" ]]; then
        SKANSIBLE_PLAY_HOST="$1"
        shift 1
    elif [[ "$1" == "homeserver" ]]; then
        SKANSIBLE_PLAY_HOST="$1"
        shift 1
    else
        echo "A playbook type must be specified"
        exit 1
    fi

    while getopts "htm:s:n:v:u:" opt; do
        case $opt in
            h) Help "init";;
            s) SKANSIBLE_STAGE="$OPTARG";;
            n) SKANSIBLE_CONN_HOST="$OPTARG";;
            v) export ANSIBLE_VERBOSITY="$OPTARG";;
            t) SKANSIBLE_UNITTEST=True;;
            u) export ANSIBLE_REMOTE_USER="$OPTARG";;
            m) SKANSIBLE_MODE="$OPTARG";;
            *) echo "Err: Invalid option set"; exit 1;;
        esac
    done

    if [ -n "$SKANSIBLE_STAGE" ]; then
        # SKANSIBLE_CONN_HOST=staging${SKANSIBLE_STAGE}.test
        if [[ "$SKANSIBLE_STAGE" == 0 ]]; then
            if [[ "$SKANSIBLE_UNITTEST" == "True" ]]; then
                sudo ansible-playbook -CKk -i hosts.yml --extra-vars "chosen_host=${SKANSIBLE_CONN_HOST}" --extra-vars "chosen_user=${ANSIBLE_REMOTE_USER:-root}" --extra-vars "mode=${SKANSIBLE_MODE}" "init@${SKANSIBLE_PLAY_HOST}.yml"
            else
                sudo ansible-playbook -Kk -i hosts.yml --extra-vars "chosen_host=${SKANSIBLE_CONN_HOST}" --extra-vars "chosen_user=${ANSIBLE_REMOTE_USER:-root}" --extra-vars "mode=${SKANSIBLE_MODE}" "init@${SKANSIBLE_PLAY_HOST}.yml"
            fi
        elif [[ "$SKANSIBLE_STAGE" == 1 ]]; then
            if [[ "$SKANSIBLE_UNITTEST" == "True" ]]; then
                sudo ansible-playbook -CK -i hosts.yml --extra-vars "chosen_host=${SKANSIBLE_CONN_HOST}" --extra-vars "chosen_user=${ANSIBLE_REMOTE_USER:-root}" --extra-vars "mode=${SKANSIBLE_MODE}" "init@${SKANSIBLE_PLAY_HOST}.yml"
            else
                sudo ansible-playbook -K -i hosts.yml --extra-vars "chosen_host=${SKANSIBLE_CONN_HOST}" --extra-vars "chosen_user=${ANSIBLE_REMOTE_USER:-root}" --extra-vars "mode=${SKANSIBLE_MODE}" "init@${SKANSIBLE_PLAY_HOST}.yml"
            fi
        fi
    else
        if [[ -z "$SKANSIBLE_CONN_HOST" ]]; then
            echo "When not doing staging, chosen or preferred host must be made explicit" 
            exit 1
        else
            sudo ansible-playbook -Kk -i hosts.yml --extra-vars "chosen_host=${SKANSIBLE_CONN_HOST}" --extra-vars "chosen_user=${ANSIBLE_REMOTE_USER:-root}" --extra-vars "mode=prod" "init@${SKANSIBLE_PLAY_HOST}.yml"
        fi
    fi

    exit 0
fi

if [[ "$1" == "bootstrap" ]]; then
    shift 1

    source "${SKANSIBLE_SCRIPT_PATH}/.env/bin/activate"

    if [[ "$1" == "vps" ]]; then
        SKANSIBLE_PLAY_HOST="$1"
        shift 1
    elif [[ "$1" == "homeserver" ]]; then
        SKANSIBLE_PLAY_HOST="$1"
        shift 1
    else
        echo "A playbook type must be specified"
        exit 1
    fi

    while getopts "htm:s:n:v:u:" opt; do
        case $opt in
            h) Help "bootstrap";;
            s) SKANSIBLE_STAGE="$OPTARG";;
            n) SKANSIBLE_CONN_HOST="$OPTARG";;
            v) export ANSIBLE_VERBOSITY=4;;
            t) SKANSIBLE_UNITTEST=True;;
            u) export ANSIBLE_REMOTE_USER="$OPTARG";;
            m) SKANSIBLE_MODE="$OPTARG";;
            *) echo "Err: Invalid option set"; exit 1;;
        esac
    done

    if [ -n "$SKANSIBLE_STAGE" ]; then
        # SKANSIBLE_CONN_HOST=staging${SKANSIBLE_STAGE}.test
        if [[ "$SKANSIBLE_STAGE" == 0 ]]; then
            if [[ "$SKANSIBLE_UNITTEST" == "True" ]]; then
                ansible-playbook -CKk -i hosts.yml --extra-vars "chosen_host=${SKANSIBLE_CONN_HOST}" --extra-vars "chosen_user=${ANSIBLE_REMOTE_USER:-senpai}" --extra-vars "mode=${SKANSIBLE_MODE}" "administrate@${SKANSIBLE_PLAY_HOST}.yml"
            else
                ansible-playbook -Kk -i hosts.yml --extra-vars "chosen_host=${SKANSIBLE_CONN_HOST}" --extra-vars "chosen_user=${ANSIBLE_REMOTE_USER:-senpai}" --extra-vars "mode=${SKANSIBLE_MODE}" "administrate@${SKANSIBLE_PLAY_HOST}.yml"
            fi
        elif [[ "$SKANSIBLE_STAGE" == 1 ]]; then
            if [[ "$SKANSIBLE_UNITTEST" == "True" ]]; then
                ansible-playbook -CK -i hosts.yml --extra-vars "chosen_host=${SKANSIBLE_CONN_HOST}" --extra-vars "chosen_user=${ANSIBLE_REMOTE_USER:-senpai}" --extra-vars "mode=${SKANSIBLE_MODE}" "administrate@${SKANSIBLE_PLAY_HOST}.yml"
            else
                ansible-playbook -K -i hosts.yml --extra-vars "chosen_host=${SKANSIBLE_CONN_HOST}" --extra-vars "chosen_user=${ANSIBLE_REMOTE_USER:-senpai}" --extra-vars "mode=${SKANSIBLE_MODE}" "administrate@${SKANSIBLE_PLAY_HOST}.yml"
            fi
        fi
    else
        if [[ -z "$SKANSIBLE_CONN_HOST" ]]; then
            echo "When not doing staging, chosen or preferred host must be made explicit" 
            exit 1
        else
            ansible-playbook -Kk -i hosts.yml --extra-vars "chosen_host=${SKANSIBLE_CONN_HOST}" --extra-vars "chosen_user=${ANSIBLE_REMOTE_USER:-senpai}" --extra-vars "mode=prod" "administrate@${SKANSIBLE_PLAY_HOST}.yml"
        fi
    fi

    exit 0
fi
