#!/usr/bin/env bash
# ===============================================================================================================
# rollback.sh - Rollback de la API backend y/o frontend de proyectosacc
# Descripción:
#       Restaura la versión anterior de la API desde backup local en la EC2.
#       Opcionalmente puede restaurar el frontend en S3 usando versionamiento.
#
# Uso:
#       bash /home/thoth/deploy/scripts/rollback.sh [api|frontend|both]
#
# Autor: Área de Tecnología y Desarrollo - CCsoft
# ===============================================================================================================

set -euo pipefail

# -------------------------------------------------------------------------------
# Configuración
# -------------------------------------------------------------------------------
ROLLBACK_TARGET="${1:-api}"
readonly APP_NAME="proyectosacc-app"
readonly ARTIFACTS_DIR="/home/thoth/deploy/artifacts"
readonly CURRENT_DIR="${ARTIFACTS_DIR}/current"
readonly BACKUP_DIR="${ARTIFACTS_DIR}/backup"
readonly SYSTEMD_SERVICE="${APP_NAME}.service"

readonly CLR_RED='\033[0;31m'
readonly CLR_GREEN='\033[0;32m'
readonly CLR_YELLOW='\033[1;33m'
readonly CLR_BLUE='\033[0;34m'
readonly CLR_NC='\033[0m'

_log_info()  { echo -e "${CLR_GREEN}[INFO]${CLR_NC} $*"; }
_log_warn()  { echo -e "${CLR_YELLOW}[WARN]${CLR_NC} $*" >&2; }
_log_error() { echo -e "${CLR_RED}[ERROR]${CLR_NC} $*" >&2; }
_log_step()  { echo ""; echo -e "${CLR_BLUE}==== $* ====${CLR_NC}"; }
_fail()      { _log_error "$*"; exit 1; }

# -------------------------------------------------------------------------------
# Rollback API
# -------------------------------------------------------------------------------
rollback_api() {
    _log_step "Iniciando rollback de la API"

    if [[ ! -d "$BACKUP_DIR" ]]; then
        _fail "Directorio de backups no encontrado: ${BACKUP_DIR}"
    fi

    local latest_backup
    latest_backup=$(ls -t "${BACKUP_DIR}/${APP_NAME}"-*.jar 2>/dev/null | head -n 1 || true)

    if [[ -z "$latest_backup" ]]; then
        _fail "No se encontraron backups de la API en ${BACKUP_DIR}"
    fi

    _log_info "Backup seleccionado: ${latest_backup}"

    # Detener servicio actual
    if systemctl is-active --quiet "${SYSTEMD_SERVICE}"; then
        sudo systemctl stop "${SYSTEMD_SERVICE}" || true
        _log_info "Servicio detenido"
    fi

    # Guardar versión fallida
    local current_jar="${CURRENT_DIR}/${APP_NAME}.jar"
    if [[ -f "$current_jar" ]]; then
        mv "$current_jar" "${current_jar}.fallo-$(date +%Y%m%d_%H%M%S)"
    fi

    # Restaurar backup
    cp "$latest_backup" "$current_jar"
    chown osiris:osiris "$current_jar"
    _log_info "Backup restaurado a ${current_jar}"

    # Reiniciar servicio
    sudo systemctl daemon-reload
    sudo systemctl start "${SYSTEMD_SERVICE}"
    _log_info "Servicio reiniciado con versión anterior"

    # Health check
    local attempt=1
    local max_retries=30
    local retry_interval=2

    while [[ $attempt -le $max_retries ]]; do
        _log_info "Health check intento ${attempt}/${max_retries}..."
        if curl -sf http://localhost:8080/actuator/health | grep -q '"status":"UP"'; then
            _log_info "Rollback de API exitoso - API saludable"
            return 0
        fi
        sleep "$retry_interval"
        ((attempt++))
    done

    _fail "Rollback de API falló - Health check no pasó"
}

# -------------------------------------------------------------------------------
# Rollback Frontend
# -------------------------------------------------------------------------------
rollback_frontend() {
    _log_step "Iniciando rollback del frontend en S3"

    local bucket="${S3_FRONTEND_BUCKET:-}"
    local distribution_id="${CLOUDFRONT_DISTRIBUTION_ID:-}"

    if [[ -z "$bucket" ]]; then
        _fail "Variable S3_FRONTEND_BUCKET no definida"
    fi

    _log_info "Listando versiones anteriores de index.html..."
    local version_id
    version_id=$(aws s3api list-object-versions \
        --bucket "$bucket" \
        --prefix index.html \
        --query 'Versions[?IsLatest==`false`].VersionId' \
        --output text 2>/dev/null | awk '{print $1}' || true)

    if [[ -z "$version_id" ]]; then
        _fail "No se encontró versión anterior de index.html en S3"
    fi

    aws s3api copy-object \
        --bucket "$bucket" \
        --copy-source "${bucket}/index.html?versionId=${version_id}" \
        --key index.html

    _log_info "index.html restaurado a versión anterior"

    if [[ -n "$distribution_id" ]]; then
        aws cloudfront create-invalidation \
            --distribution-id "$distribution_id" \
            --paths "/*"
        _log_info "Invalidación de CloudFront creada"
    else
        _log_warn "CLOUDFRONT_DISTRIBUTION_ID no definido, omitiendo invalidación"
    fi
}

# -------------------------------------------------------------------------------
# Main
# -------------------------------------------------------------------------------
main() {
    case "$ROLLBACK_TARGET" in
        api)
            rollback_api
            ;;
        frontend)
            rollback_frontend
            ;;
        both)
            rollback_api
            rollback_frontend
            ;;
        *)
            echo "Uso: $0 [api|frontend|both]"
            exit 1
            ;;
    esac

    _log_info "Rollback completado"
}

main "$@"
