#!/bin/bash
# ==========================================
# Monitoring Stack Installer (Public Wrapper)
# ==========================================
# Hosted on: https://hub.friendly-tech.com/bootstrap/install.sh
#
# Usage:
#   curl -fsSL https://hub.friendly-tech.com/bootstrap/install.sh | sudo bash -s -- PROMETHEUS_IP [node-type]
#
# Examples:
#   # Auto-detect OS (recommended)
#   curl -fsSL https://hub.friendly-tech.com/bootstrap/install.sh | sudo bash -s -- 65.109.58.165
#
#   # Specify node type
#   curl -fsSL https://hub.friendly-tech.com/bootstrap/install.sh | sudo bash -s -- 65.109.58.165 mysql
#
#   # Deploy Prometheus + Grafana stack (on the monitoring server itself)
#   curl -fsSL https://hub.friendly-tech.com/bootstrap/install.sh | sudo bash -s -- stack
#
# ==========================================

set -euo pipefail

# Ensure valid working directory (avoid "getcwd: cannot access parent directories"
# when user's CWD was deleted, e.g. after removing /opt/grafana)
cd /tmp 2>/dev/null || cd /

# Colors
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
CYAN='\033[0;36m'
NC='\033[0m'

log_info() { echo -e "${GREEN}✓${NC} $*"; }
log_warn() { echo -e "${YELLOW}⚠${NC} $*"; }
log_error() { echo -e "${RED}✗${NC} $*"; }
log_step() { echo -e "\n${BLUE}▶${NC} ${CYAN}$*${NC}"; }

# Show available versions (tags and branches)
show_versions() {
    local HUB_BASE_URL="https://hub.friendly-tech.com/bootstrap"
    local REPO_CLONE_URL="${HUB_BASE_URL}/repo-url"

    # Get token from hub
    local GITHUB_REPO_URL
    GITHUB_REPO_URL=$(curl -sS -f "$REPO_CLONE_URL" 2>/dev/null) || {
        log_error "Failed to get repository access from hub"
        exit 1
    }

    local GITHUB_TOKEN
    GITHUB_TOKEN=$(echo "$GITHUB_REPO_URL" | sed -n 's|https://\([^@]*\)@github.com/.*|\1|p')

    echo ""
    echo "Available versions:"
    echo ""

    # Get ALL tags (releases) via GitHub API - need all for comparison
    local TAGS_RAW
    TAGS_RAW=$(curl -sS -H "Authorization: token ${GITHUB_TOKEN}" \
        "https://api.github.com/repos/Friendly-Technologies/grafana/tags?per_page=100" \
        2>/dev/null | grep '"name"' | sed 's/.*"name": "\([^"]*\)".*/\1/')

    # Display released versions (limit to 10)
    echo "  Released:"
    if [[ -n "$TAGS_RAW" ]]; then
        echo "$TAGS_RAW" | head -1 | sed 's/^/    /' | sed 's/$/ (latest)/'
        echo "$TAGS_RAW" | tail -n +2 | head -9 | sed 's/^/    /'
    else
        echo "    (unable to fetch)"
    fi

    echo ""

    # Get branches (exclude main and feature branches)
    echo "  In development:"
    local BRANCHES_RAW
    BRANCHES_RAW=$(curl -sS -H "Authorization: token ${GITHUB_TOKEN}" \
        "https://api.github.com/repos/Friendly-Technologies/grafana/branches?per_page=100" \
        2>/dev/null | grep '"name"' | grep -v '"main"' | grep -E '"[0-9]+\.[0-9]+\.[0-9]+"' | sed 's/.*"name": "\([^"]*\)".*/\1/')

    # Filter out branches that have tags (already released)
    local DEV_BRANCHES=""
    for branch in $BRANCHES_RAW; do
        if ! echo "$TAGS_RAW" | grep -qx "${branch}"; then
            DEV_BRANCHES="${DEV_BRANCHES}    ${branch}\n"
        fi
    done

    if [[ -n "$DEV_BRANCHES" ]]; then
        echo -e "$DEV_BRANCHES" | grep -v '^$' | head -10
    else
        echo "    (none)"
    fi

    echo ""
    echo "Usage:"
    echo "  curl -fsSL https://hub.friendly-tech.com/bootstrap/install.sh | sudo bash -s -- --branch <version>"
    echo ""
}

# Banner
echo ""
echo "=========================================="
echo "  Friendly Technologies"
echo "  Monitoring Stack Installer"
echo "=========================================="
echo ""

# ==========================================
# Configuration
# ==========================================

HUB_BASE_URL="https://hub.friendly-tech.com/bootstrap"
REPO_CLONE_URL="${HUB_BASE_URL}/repo-url"
# The version this installer belongs to. It used to be `main`, which is the last
# RELEASED state — so anyone following the 1.6.9 documentation without passing
# `--branch` silently got a different version from the one they were reading,
# and the docs contradicted themselves about it.
#
# Bumped with the release, and kept honest by misc/check-versions.sh: a mismatch
# with VERSION fails the pre-commit hook rather than shipping a stale default.
REPO_BRANCH="1.6.9"

# ==========================================
# Parse Arguments
# ==========================================

PROMETHEUS_IP=""
NODE_TYPE="auto"
EXTRA_ARGS=()
ROLLBACK_MODE=false
LIST_MANIFESTS=false
DIAGNOSE_MODE=false
RESET_PASSWORD=false
UPDATE_MODE=false

# Parse all arguments
while [[ $# -gt 0 ]]; do
    case "$1" in
        --reset-password|--reset-prometheus-password)
            RESET_PASSWORD=true
            EXTRA_ARGS+=("$1")
            shift
            # Capture optional password argument
            if [[ -n "${1:-}" ]] && [[ ! "$1" =~ ^- ]]; then
                EXTRA_ARGS+=("$1")
                shift
            fi
            ;;
        --update|--update-only)
            # Code-only refresh: no IP, nothing deployed. Forwarded to bootstrap,
            # which takes no positional args in this mode.
            UPDATE_MODE=true
            EXTRA_ARGS+=("$1")
            shift
            ;;
        --diagnose)
            DIAGNOSE_MODE=true
            EXTRA_ARGS+=("$1")
            shift
            ;;
        --rollback)
            ROLLBACK_MODE=true
            EXTRA_ARGS+=("$1")
            shift
            # Check for optional manifest path
            if [[ -n "${1:-}" ]] && [[ ! "$1" =~ ^- ]]; then
                EXTRA_ARGS+=("$1")
                shift
            fi
            ;;
        --list-manifests)
            LIST_MANIFESTS=true
            EXTRA_ARGS+=("$1")
            shift
            ;;
        --version-list|--versions|-l)
            show_versions
            exit 0
            ;;
        --help|-h)
            echo ""
            echo "Usage:"
            echo "  curl -fsSL https://hub.friendly-tech.com/bootstrap/install.sh | \\"
            echo "    sudo bash -s -- PROMETHEUS_IP [node-type] [OPTIONS]"
            echo ""
            echo "Arguments:"
            echo "  PROMETHEUS_IP  - IP address of Prometheus server (required)"
            echo "  node-type      - Optional: ubuntu, centos, mysql, oracle, stack (default: auto)"
            echo ""
            echo "Options:"
            echo "  --help, -h            Show this help"
            echo "  --version, -v         Show version"
            echo "  --prefix NAME         Instance name prefix (default: DevOps)"
            echo "  --branch VERSION      Install specific version (default: 1.6.9)"
            echo "  --version-list, -l    Show all available versions"
            echo "  --rollback [MANIFEST] Rollback deployment changes"
            echo "  --list-manifests      List available rollback manifests"
            echo "  --diagnose            Collect system diagnostics into a report file"
        echo "  --update              Pull new code into /opt/grafana and stop: no deploy,"
        echo "                        no restart, no IP needed. Use with --branch."
            echo "  --fix-storage-driver  Switch Docker 'overlayfs' -> 'overlay2' (restarts Docker);"
            echo "                        required for cAdvisor container metrics"
            echo "  --reset-password [PW] Reset Grafana admin password"
            echo "  --reset-prometheus-password [PW] Reset Prometheus basic auth password"
            echo "  --docs                Show documentation links"
            echo ""
            echo "Examples:"
            echo "  curl ... | sudo bash -s -- 65.109.58.165         # Auto-detect OS"
            echo "  curl ... | sudo bash -s -- stack                 # Prometheus+Grafana"
            echo "  curl ... | sudo bash -s -- stack --branch 1.6.6  # Specific version"
            echo "  curl ... | sudo bash -s -- --rollback            # Rollback changes"
            echo "  curl ... | sudo bash -s -- --diagnose            # Generate diagnostic report"
            echo ""
            exit 0
            ;;
        --version|-v)
            echo "Monitoring Stack Installer"
            echo "Version: 1.6.9 (default branch: 1.6.9)"
            echo ""
            echo "Use --version-list to see all available versions"
            exit 0
            ;;
        --docs|--readme)
            echo ""
            echo "Documentation:"
            echo ""
            echo "  Online:  https://docs-friendly-tech.pages.dev"
            echo "  PDF:     https://hub.friendly-tech.com/docs/pdf/"
            echo ""
            echo "PDF documents:"
            echo "  - README       - Installation guide"
            echo "  - sizing       - Resource requirements"
            echo "  - architecture - System overview"
            echo ""
            exit 0
            ;;
        --branch)
            if [[ -n "${1:-}" ]]; then
                REPO_BRANCH="$2"
                EXTRA_ARGS+=("$1" "$2")
                shift 2
            fi
            ;;
        --branch=*)
            REPO_BRANCH="${1#*=}"
            EXTRA_ARGS+=("$1")
            shift
            ;;
        --prefix|--token)
            EXTRA_ARGS+=("$1")
            shift
            if [[ -n "${1:-}" ]]; then
                EXTRA_ARGS+=("$1")
                shift
            fi
            ;;
        --prefix=*|--token=*)
            EXTRA_ARGS+=("$1")
            shift
            ;;
        -*)
            EXTRA_ARGS+=("$1")
            shift
            ;;
        *)
            # Positional arguments
            if [[ -z "$PROMETHEUS_IP" ]]; then
                PROMETHEUS_IP="$1"
            elif [[ "$NODE_TYPE" == "auto" ]]; then
                NODE_TYPE="$1"
            fi
            shift
            ;;
    esac
done

# Handle rollback/list-manifests/diagnose modes (no IP needed)
if [[ "$ROLLBACK_MODE" == true ]] || [[ "$LIST_MANIFESTS" == true ]] || [[ "$DIAGNOSE_MODE" == true ]] || [[ "$RESET_PASSWORD" == true ]] || [[ "$UPDATE_MODE" == true ]]; then
    log_info "Maintenance mode"
else
    # Show usage if no arguments
    if [[ -z "$PROMETHEUS_IP" ]]; then
        log_error "Missing required argument: PROMETHEUS_IP"
        echo ""
        echo "Usage:"
        echo "  curl -fsSL https://hub.friendly-tech.com/bootstrap/install.sh | \\"
        echo "    sudo bash -s -- PROMETHEUS_IP [node-type] [OPTIONS]"
        echo ""
        echo "Arguments:"
        echo "  PROMETHEUS_IP  - IP address of Prometheus server (required)"
        echo "  node-type      - Optional: ubuntu, centos, mysql, oracle, stack (default: auto)"
        echo ""
        echo "Options:"
        echo "  --help, -h            Show help"
        echo "  --version, -v         Show version"
        echo "  --prefix NAME         Instance name prefix (default: DevOps)"
        echo "  --branch VERSION      Install specific version (default: 1.6.9)"
        echo "  --version-list, -l    Show all available versions"
        echo "  --rollback [MANIFEST] Rollback deployment changes"
        echo "  --list-manifests      List available rollback manifests"
        echo "  --diagnose            Collect system diagnostics into a report file"
        echo "  --update              Pull new code into /opt/grafana and stop: no deploy,"
        echo "                        no restart, no IP needed. Use with --branch."
        echo "  --docs                Show documentation links"
        echo ""
        echo "Examples:"
        echo "  # Auto-detect OS (recommended for most servers)"
        echo "  curl -fsSL https://hub.friendly-tech.com/bootstrap/install.sh | \\"
        echo "    sudo bash -s -- 65.109.58.165"
        echo ""
        echo "  # Rollback deployment"
        echo "  curl -fsSL https://hub.friendly-tech.com/bootstrap/install.sh | \\"
        echo "    sudo bash -s -- --rollback"
        echo ""
        echo "  # Prometheus + Grafana monitoring stack"
        echo "  curl -fsSL https://hub.friendly-tech.com/bootstrap/install.sh | \\"
        echo "    sudo bash -s -- stack"
        echo ""
        exit 1
    fi

    # Handle "stack" as special case (no Prometheus IP needed - this IS the Prometheus server)
    if [[ "$PROMETHEUS_IP" == "stack" ]]; then
        NODE_TYPE="stack"
        PROMETHEUS_IP="127.0.0.1"
        log_info "Stack deployment mode"
    elif ! [[ "$PROMETHEUS_IP" =~ ^[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+$ ]]; then
        log_error "Invalid IP address format: $PROMETHEUS_IP"
        exit 1
    fi

    log_info "Prometheus IP: $PROMETHEUS_IP"
    log_info "Node type: $NODE_TYPE"
fi

# Check if running as root
if [[ $EUID -ne 0 ]]; then
    log_error "This script must be run as root (use sudo)"
    exit 1
fi

# ==========================================
# Install prerequisites (curl, git)
# ==========================================

install_if_missing() {
    local cmd="$1"
    local pkg="${2:-$1}"

    if command -v "$cmd" &>/dev/null; then
        return 0
    fi

    log_warn "$cmd not found, installing..."

    if command -v apt-get &>/dev/null; then
        apt-get update && apt-get install -y "$pkg"
    elif command -v dnf &>/dev/null; then
        dnf install -y "$pkg"
    elif command -v yum &>/dev/null; then
        yum install -y "$pkg"
    else
        log_error "Cannot install $pkg: no supported package manager"
        return 1
    fi

    if ! command -v "$cmd" &>/dev/null; then
        log_error "Failed to install $pkg"
        return 1
    fi

    log_info "$pkg installed"
}

# Ensure curl and git are available
install_if_missing curl || exit 1
install_if_missing git || exit 1

# ==========================================
# Get authenticated repo URL from hub
# ==========================================

log_step "Retrieving repository access..."

GITHUB_REPO_URL=$(curl -sS -f "$REPO_CLONE_URL" 2>/dev/null) || {
    log_error "Failed to get repository URL from hub"
    echo "Please contact administrator"
    exit 1
}

if [[ -z "$GITHUB_REPO_URL" ]]; then
    log_error "Empty repository URL received"
    exit 1
fi

# Extract token from repo URL (format: https://TOKEN@github.com/...)
GITHUB_TOKEN=$(echo "$GITHUB_REPO_URL" | sed -n 's|https://\([^@]*\)@github.com/.*|\1|p')

if [[ -z "$GITHUB_TOKEN" ]]; then
    log_error "Failed to extract token from repository URL"
    exit 1
fi

log_info "Repository access configured"

# ==========================================
# Download Bootstrap Script from GitHub
# ==========================================

log_step "Downloading bootstrap script..."

BOOTSTRAP_TMP="/tmp/bootstrap-$$.sh"

# Use GitHub API instead of raw.githubusercontent.com to avoid CDN caching
BOOTSTRAP_URL="https://api.github.com/repos/Friendly-Technologies/grafana/contents/misc/bootstrap.sh?ref=${REPO_BRANCH}"

HTTP_CODE=$(curl -sS -w "%{http_code}" \
    -H "Authorization: token ${GITHUB_TOKEN}" \
    -H "Accept: application/vnd.github.v3.raw" \
    -o "$BOOTSTRAP_TMP" \
    "$BOOTSTRAP_URL" 2>/dev/null)

if [[ "$HTTP_CODE" != "200" ]]; then
    log_error "Failed to download bootstrap script (HTTP $HTTP_CODE)"
    rm -f "$BOOTSTRAP_TMP"
    exit 1
fi

log_info "Bootstrap script downloaded"

# Make executable
chmod +x "$BOOTSTRAP_TMP"

# ==========================================
# Run Bootstrap
# ==========================================

log_step "Running bootstrap..."
echo ""

# Export for bootstrap to use
export GITHUB_REPO_URL="$GITHUB_REPO_URL"
export GITHUB_TOKEN="$GITHUB_TOKEN"
export REPO_BRANCH="$REPO_BRANCH"

# Run bootstrap with all arguments
# Filter "getcwd" errors from stderr (occurs when user's CWD was deleted before running install)
if [[ "$ROLLBACK_MODE" == true ]] || [[ "$LIST_MANIFESTS" == true ]] || [[ "$DIAGNOSE_MODE" == true ]] || [[ "$UPDATE_MODE" == true ]]; then
    # Maintenance mode - only pass extra args (no IP, no node type)
    bash "$BOOTSTRAP_TMP" "${EXTRA_ARGS[@]}" 2> >(grep -v "getcwd\|job-working-directory" >&2)
else
    # Normal mode - pass IP, node type, and any extra args
    if [[ ${#EXTRA_ARGS[@]} -gt 0 ]]; then
        bash "$BOOTSTRAP_TMP" "$PROMETHEUS_IP" "$NODE_TYPE" "${EXTRA_ARGS[@]}" 2> >(grep -v "getcwd\|job-working-directory" >&2)
    else
        bash "$BOOTSTRAP_TMP" "$PROMETHEUS_IP" "$NODE_TYPE" 2> >(grep -v "getcwd\|job-working-directory" >&2)
    fi
fi

# Cleanup
rm -f "$BOOTSTRAP_TMP"

log_info "Installation complete!"
