#!/usr/bin/env bash
# atomic-red-team.sh - install/remove Atomic Red Team support on Debian 13 (trixie):
# PowerShell (pwsh, from the GitHub release deb - no MS apt repo), the
# invoke-atomicredteam PSGallery module, and a shallow clone of the ART index.
# This script NEVER executes any atomic tests; it only prepares the tooling.
# Usage: sudo ./atomic-red-team.sh add|remove|status

set -euo pipefail

ART_DIR=/opt/atomic-red-team

# Re-exec with sudo if not root
if [[ ${EUID} -ne 0 ]]; then
    exec sudo -E "$0" "$@"
fi

usage() {
    echo "Usage: $0 {add|remove|status}"
    exit 2
}

pwsh_version() {
    pwsh --version 2>/dev/null || true
}

module_installed() {
    pwsh -NoProfile -Command "if (Get-Command Invoke-AtomicTest -ErrorAction SilentlyContinue) { exit 0 } else { exit 1 }" >/dev/null 2>&1
}

install_pwsh() {
    if command -v pwsh >/dev/null 2>&1; then
        echo "[*] pwsh already installed: $(pwsh_version)"
        return 0
    fi

    echo "[*] Resolving latest PowerShell release from the GitHub API"
    export DEBIAN_FRONTEND=noninteractive
    apt-get update -y || true
    apt-get install -y ca-certificates curl

    local deb_url
    deb_url=$(curl -fsSL https://api.github.com/repos/PowerShell/PowerShell/releases/latest \
        | grep -oE '"browser_download_url": *"[^"]*/powershell_[^"/]*deb_amd64\.deb"' \
        | head -n1 | grep -oE 'https[^"]*')
    if [[ -z ${deb_url} ]]; then
        echo "[!] could not resolve a powershell_*deb_amd64.deb asset URL" >&2
        exit 1
    fi
    echo "[*] Downloading ${deb_url}"
    local deb=/tmp/powershell-deb_amd64.deb
    curl -fSL -o "${deb}" "${deb_url}"

    echo "[*] Installing PowerShell deb (dpkg + apt-get -f for deps)"
    dpkg -i "${deb}" || apt-get -f install -y
    rm -f "${deb}"

    local ver
    ver=$(pwsh_version)
    [[ -n ${ver} ]] || { echo "[!] pwsh not usable after install" >&2; exit 1; }
    echo "[+] pwsh installed: ${ver}"
}

install_module() {
    if module_installed; then
        echo "[*] invoke-atomicredteam module already installed"
        return 0
    fi

    echo "[*] Installing invoke-atomicredteam from PSGallery (AllUsers, non-interactive)"
    pwsh -NoProfile -Command "Set-PSRepository -Name PSGallery -InstallationPolicy Trusted; Install-Module -Name invoke-atomicredteam -Scope AllUsers -Force -AllowClobber"

    local name
    name=$(pwsh -NoProfile -Command "Get-Command Invoke-AtomicTest | Select-Object -ExpandProperty Name" 2>/dev/null || true)
    [[ ${name} == "Invoke-AtomicTest" ]] || { echo "[!] Invoke-AtomicTest not available after module install" >&2; exit 1; }
    echo "[+] invoke-atomicredteam module installed"
}

clone_index() {
    if [[ -d ${ART_DIR} ]]; then
        echo "[*] ${ART_DIR} already exists; skipping clone"
    else
        echo "[*] Cloning the ART index to ${ART_DIR} (shallow)"
        git clone --depth 1 https://github.com/redcanaryco/atomic-red-team.git "${ART_DIR}"
    fi
}

add() {
    install_pwsh
    install_module
    clone_index
    echo "[i] No atomic tests were executed by this script. Inspect a test with:"
    echo "[i]   pwsh -NoProfile -Command \"Invoke-AtomicTest T1056.001 -ShowDetails\"   (-PromptForInputElseYolo / -Execute is the operator's choice)"
    echo "[+] Atomic Red Team tooling installed"
}

remove() {
    export DEBIAN_FRONTEND=noninteractive

    if module_installed || command -v pwsh >/dev/null 2>&1; then
        echo "[*] Uninstalling invoke-atomicredteam module (all versions)"
        pwsh -NoProfile -Command "Uninstall-Module -Name invoke-atomicredteam -AllVersions -Force" 2>/dev/null || true
    fi

    if dpkg -s powershell >/dev/null 2>&1; then
        echo "[*] Purging the powershell package"
        apt-get purge -y powershell
        apt-get autoremove --purge -y
    fi

    if [[ -d ${ART_DIR} ]]; then
        echo "[*] Removing ${ART_DIR}"
        rm -rf "${ART_DIR}"
    fi

    # Remove any per-user ART module cache dirs
    local home_dir d
    for home_dir in /root /home/*; do
        [[ -d ${home_dir} ]] || continue
        for d in "${home_dir}/AtomicRedTeam" "${home_dir}/.local/share/powershell/Modules/invoke-atomicredteam"; do
            if [[ -d ${d} ]]; then
                echo "[*] Removing ${d}"
                rm -rf "${d}"
            fi
        done
    done

    echo "[+] Atomic Red Team tooling removed"
}

status() {
    local ver
    ver=$(pwsh_version)
    if [[ -n ${ver} ]]; then
        echo "[*] pwsh: ${ver}"
    else
        echo "[*] pwsh: not installed"
    fi

    if module_installed; then
        echo "[*] invoke-atomicredteam module: installed"
    else
        echo "[*] invoke-atomicredteam module: not installed"
    fi

    if [[ -d ${ART_DIR}/atomics ]]; then
        echo "[*] ${ART_DIR}: present ($(ls -1 "${ART_DIR}/atomics" | wc -l) atomics entries)"
    elif [[ -d ${ART_DIR} ]]; then
        echo "[*] ${ART_DIR}: present (no atomics dir)"
    else
        echo "[*] ${ART_DIR}: absent"
    fi

    echo "[i] No atomic tests have been run by this script."
}

case "${1:-}" in
    add)    add ;;
    remove) remove ;;
    status) status ;;
    *)      usage ;;
esac
