#!/usr/bin/env bash

set -euo pipefail

# This script is responsible for generating a file containing all the public keys for various users that should be on
# vehicle

# List of users whose keys should be in the user_keys file
USERS_LIST=("sk" "vince" "felix")

# Namespace in vault where user keys are defined
VAULT_USER_NAMESPACE="secret/user/ssh"

# Namespace in vault where robot keys are defined
VAULT_ROBOT_NAMESPACE="secret/robot/ssh"

# List of operators whose keys needs to be fetched
VAULT_OPERATOR_NAMESPACE="secret/operator/ssh"

# Zweb's bucket
ZWEB_PATH="s3://zoox-web/robot-ssh-authorized-keys"

# prefix site where one can retrieve the keys file
SITE_PREFIX="https://robot-ssh-authorized-keys.zooxlabs.com"

# URL of the vault service
VAULT_ADDR="https://vault.zooxlabs.com:8200"

# Field in the vault key to get the token
VAULT_FIELD="ssh_public_key"

# List of robots whose keys should be in the robot_keys file
ROBOTS_LIST=($(VAULT_ADDR="${VAULT_ADDR}" vault list -format=json "${VAULT_ROBOT_NAMESPACE}" | jq --raw-output .[] | tr "\n" " "))

# List of operators whose keys should be in the operator_keys file
OPERATORS_LIST=($(VAULT_ADDR="${VAULT_ADDR}" vault list -format=json "${VAULT_OPERATOR_NAMESPACE}" | jq --raw-output .[] | tr "\n" " "))

function generate_and_upload() {
    # Generates and uploads the file to zweb. Takes three arguments
    # 1. Name of the file in zweb to upload to
    # 2. vault namespace
    # 3. list of users

    # Name of the file to which keys would be uploaded to
    FILE="$1"
    shift

    # Vault namespace to be used.
    NAMESPACE="$1"
    shift

    # List of users whose ssh_public_key would be fetched
    LIST=("$@")

    # URL where the keys file would be present
    URL="${SITE_PREFIX}/${FILE}"

    # Path of the temporary file where the ssh keys of list would be added
    AUTHORIZED_KEYS_FILE_PATH=$(tempfile)

    # Path of the temporary file where the existing keys in zweb would be downloaded.
    EXISTING_AUTHORIZED_KEYS_FILE_PATH=$(tempfile)

    # Generate the keys file from vault
    for item in "${LIST[@]}"
    do
        public_key=$(VAULT_ADDR="${VAULT_ADDR}" vault read -field="${VAULT_FIELD}" "${NAMESPACE}/${item}")
        echo "${public_key}" >> "${AUTHORIZED_KEYS_FILE_PATH}"
    done

    # Get the existing content and do a diff
    curl --fail --silent "${URL}" > "${EXISTING_AUTHORIZED_KEYS_FILE_PATH}"

    # compare the file
    echo "Comparing existing file (left) with the new generated file (right)"

    set +e
    changes=$(diff "${EXISTING_AUTHORIZED_KEYS_FILE_PATH}" "${AUTHORIZED_KEYS_FILE_PATH}")
    set -e

    if [[ -z "${changes}" ]];
    then
        echo "There are no changes to ${URL}, skipping...."
        return
    else
        echo "${changes}"
    fi

    echo -n "Is the diff looking good and continue [n]: "
    read should_continue

    if [[ "${should_continue}" == "y" ]];
    then
        # Copy the file to S3
        aws s3 cp "${AUTHORIZED_KEYS_FILE_PATH}" "${ZWEB_PATH}/${FILE}"

        echo "Uploaded the file to ${URL}"
    else
       echo "Not uploading the file ${AUTHORIZED_KEYS_FILE_PATH}"
    fi

}

generate_and_upload "user_keys" "${VAULT_USER_NAMESPACE}" "${USERS_LIST[@]}"
generate_and_upload "robot_keys" "${VAULT_ROBOT_NAMESPACE}" "${ROBOTS_LIST[@]}"
generate_and_upload "operator_keys" "${VAULT_OPERATOR_NAMESPACE}" "${OPERATORS_LIST[@]}"
