#!/bin/sh
# Tests for scripts/install.sh
#
# Runs install.sh in isolated Docker containers across multiple distros.
# Verifies OS/arch detection, install dir logic, error handling, and
# the download attempt (expects 404 since no release may exist yet).
#
# Usage:
#   sh scripts/test-install.sh               # run all tests
#   sh scripts/test-install.sh --local       # run host-only tests (no Docker)
#
# Requires: Docker (for cross-distro tests), or --local for just shellcheck + syntax

set -e

SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
INSTALL_SCRIPT="${SCRIPT_DIR}/install.sh"
PASS=0
FAIL=0

# --- helpers ---

green() { printf '\033[32m%s\033[0m\n' "$1"; }
red()   { printf '\033[31m%s\033[0m\n' "$1"; }

assert_contains() {
    label="$1"
    haystack="$2"
    needle="$3"
    if echo "$haystack" | grep -q "$needle"; then
        green "  PASS: $label"
        PASS=$((PASS + 1))
    else
        red "  FAIL: $label — expected '$needle' in output"
        echo "  got: $haystack"
        FAIL=$((FAIL + 1))
    fi
}

assert_exit() {
    label="$1"
    expected="$2"
    actual="$3"
    if [ "$expected" = "$actual" ]; then
        green "  PASS: $label"
        PASS=$((PASS + 1))
    else
        red "  FAIL: $label — expected exit $expected, got $actual"
        FAIL=$((FAIL + 1))
    fi
}

# --- local tests (no Docker) ---

test_syntax() {
    echo "== Syntax check =="
    out=$(sh -n "$INSTALL_SCRIPT" 2>&1)
    assert_exit "sh -n (POSIX syntax)" "0" "$?"
}

test_shellcheck() {
    echo "== Shellcheck =="
    if command -v shellcheck > /dev/null 2>&1; then
        out=$(shellcheck "$INSTALL_SCRIPT" 2>&1)
        assert_exit "shellcheck clean" "0" "$?"
    else
        green "  SKIP: shellcheck not installed"
        PASS=$((PASS + 1))
    fi
}

test_host_detection() {
    echo "== Host OS/arch detection =="
    expected_os=""
    case "$(uname -s)" in
        Linux*)  expected_os="linux" ;;
        Darwin*) expected_os="darwin" ;;
    esac
    expected_arch=""
    case "$(uname -m)" in
        x86_64|amd64)   expected_arch="amd64" ;;
        aarch64|arm64)  expected_arch="arm64" ;;
    esac

    out=$(KUBEROKU_VERSION=v0.0.0-test sh "$INSTALL_SCRIPT" 2>&1 || true)
    assert_contains "detects OS as $expected_os" "$out" "platform: ${expected_os}/"
    assert_contains "detects arch as $expected_arch" "$out" "platform: ${expected_os}/${expected_arch}"
}

test_custom_install_dir() {
    echo "== Custom install dir =="
    tmpdir=$(mktemp -d)
    out=$(KUBEROKU_VERSION=v0.0.0-test KUBEROKU_INSTALL_DIR="$tmpdir" sh "$INSTALL_SCRIPT" 2>&1 || true)
    assert_contains "uses custom dir" "$out" "target:   ${tmpdir}/kuberoku"
    rm -rf "$tmpdir"
}

test_pinned_version() {
    echo "== Pinned version =="
    out=$(KUBEROKU_VERSION=v1.2.3 sh "$INSTALL_SCRIPT" 2>&1 || true)
    assert_contains "uses pinned version" "$out" "version:  v1.2.3"
    assert_contains "correct download URL" "$out" "downloading https://github.com/amanjain/kuberoku/releases/download/v1.2.3/"
}

# --- Docker-based distro tests ---

test_in_docker() {
    image="$1"
    label="$2"
    expected_os="$3"

    echo "== $label ($image) =="

    # Skip if image is not available for this platform
    if ! docker pull -q "$image" > /dev/null 2>&1; then
        green "  SKIP: $label — image not available for $(uname -m)"
        PASS=$((PASS + 1))
        return
    fi

    out=$(docker run --rm \
        -v "${SCRIPT_DIR}:/scripts:ro" \
        "$image" \
        sh -c 'KUBEROKU_VERSION=v0.0.0-test sh /scripts/install.sh 2>&1 || true' 2>&1)

    assert_contains "$label: detects OS" "$out" "platform: ${expected_os}/"
    assert_contains "$label: attempts download" "$out" "downloading https://github.com/amanjain/kuberoku"
}

# --- main ---

run_local_tests() {
    test_syntax
    test_shellcheck
    test_host_detection
    test_custom_install_dir
    test_pinned_version
}

run_docker_tests() {
    test_in_docker "alpine:latest"          "Alpine (BusyBox sh)"    "linux"
    test_in_docker "ubuntu:22.04"           "Ubuntu 22.04 (dash)"   "linux"
    test_in_docker "debian:bookworm-slim"   "Debian Bookworm"       "linux"
    test_in_docker "fedora:40"              "Fedora 40 (bash)"      "linux"
    test_in_docker "archlinux:latest"       "Arch Linux"            "linux"
    test_in_docker "amazonlinux:2023"       "Amazon Linux 2023"     "linux"
}

main() {
    echo "Testing: $INSTALL_SCRIPT"
    echo ""

    run_local_tests

    if [ "${1:-}" = "--local" ]; then
        echo ""
        echo "Skipping Docker tests (--local)"
    else
        if command -v docker > /dev/null 2>&1; then
            echo ""
            run_docker_tests
        else
            echo ""
            echo "Skipping Docker tests (docker not found)"
        fi
    fi

    echo ""
    echo "==============================="
    green "Passed: $PASS"
    if [ "$FAIL" -gt 0 ]; then
        red "Failed: $FAIL"
        exit 1
    else
        echo "Failed: 0"
    fi
}

main "$@"
