#!/bin/bash
# =============================================================================
# SQL Server 2017 Express - Configuración Optimizada para Bajo Consumo de RAM
# =============================================================================
# Uso: ./start.db.sh [start|stop|restart|status|optimize|logs]
# =============================================================================

set -e

CONTAINER_NAME="mssql2017"
SA_PASSWORD="Asde71.4Asde71.4"
DATA_DIR="/home/andres/mssql/data"
LOG_DIR="/home/andres/mssql/log"

# Colores
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
NC='\033[0m'

log_info() { echo -e "${GREEN}[INFO]${NC} $1"; }
log_warn() { echo -e "${YELLOW}[WARN]${NC} $1"; }
log_error() { echo -e "${RED}[ERROR]${NC} $1"; }

wait_for_sql() {
    log_info "Esperando que SQL Server inicie..."
    for i in {1..30}; do
        if docker exec $CONTAINER_NAME /opt/mssql-tools/bin/sqlcmd \
            -S localhost -U sa -P "$SA_PASSWORD" \
            -Q "SELECT 1" &>/dev/null; then
            log_info "SQL Server listo"
            return 0
        fi
        sleep 2
    done
    log_error "SQL Server no respondió en 60 segundos"
    return 1
}

apply_optimizations() {
    log_info "Aplicando optimizaciones de rendimiento y estabilidad..."

    docker exec $CONTAINER_NAME /opt/mssql-tools/bin/sqlcmd \
        -S localhost -U sa -P "$SA_PASSWORD" -Q "
-- =============================================
-- OPTIMIZACIONES PARA BAJO CONSUMO + ESTABILIDAD
-- =============================================

-- Habilitar opciones avanzadas
EXEC sp_configure 'show advanced options', 1;
RECONFIGURE;

-- MAX SERVER MEMORY: Limitar buffer pool
EXEC sp_configure 'max server memory', 384;
RECONFIGURE;

-- MIN SERVER MEMORY: Permitir liberar bajo presión
EXEC sp_configure 'min server memory', 128;
RECONFIGURE;

-- OPTIMIZE FOR AD HOC: Reduce cache de planes únicos
EXEC sp_configure 'optimize for ad hoc workloads', 1;
RECONFIGURE;

-- MAXDOP: Limitar paralelismo (reduce RAM en operaciones paralelas)
EXEC sp_configure 'max degree of parallelism', 2;
RECONFIGURE;

-- COST THRESHOLD: Solo queries costosas usan paralelismo
EXEC sp_configure 'cost threshold for parallelism', 50;
RECONFIGURE;

-- RECOVERY INTERVAL: Checkpoints frecuentes = recuperación rápida
EXEC sp_configure 'recovery interval (min)', 1;
RECONFIGURE;

-- TRACE FLAGS para estabilidad
DBCC TRACEON(3226, -1); -- Suprime logs de backup exitoso
DBCC TRACEON(1118, -1); -- Reduce contención tempdb
DBCC TRACEON(1117, -1); -- Crecimiento uniforme de archivos

PRINT 'Optimizaciones aplicadas correctamente';
" 2>/dev/null

    log_info "Optimizaciones aplicadas"
}

start_container() {
    if docker ps -q -f name=$CONTAINER_NAME | grep -q .; then
        log_warn "El contenedor ya está corriendo"
        return 0
    fi

    # Eliminar contenedor existente si está detenido
    docker rm -f $CONTAINER_NAME 2>/dev/null || true

    # Crear directorios si no existen
    mkdir -p "$DATA_DIR" "$LOG_DIR"

    log_info "Iniciando SQL Server 2017 Express (512MB RAM)..."

    docker run -d \
        --name $CONTAINER_NAME \
        --memory="384m" \
        --memory-swap="4g" \
        --memory-reservation="384m" \
        --restart=unless-stopped \
        -e "ACCEPT_EULA=Y" \
        -e "MSSQL_SA_PASSWORD=$SA_PASSWORD" \
        -e "MSSQL_PID=Express" \
        -e "MSSQL_MEMORY_LIMIT_MB=340" \
        -v "$DATA_DIR:/var/opt/mssql/data" \
        -v "$LOG_DIR:/var/opt/mssql/log" \
        -p 1433:1433 \
        mcr.microsoft.com/mssql/server:2017-latest

    wait_for_sql
    apply_optimizations

    log_info "SQL Server iniciado y optimizado"
    show_status
}

stop_container() {
    log_info "Deteniendo SQL Server..."
    docker stop $CONTAINER_NAME 2>/dev/null || true
    log_info "SQL Server detenido"
}

show_status() {
    echo ""
    echo "=== Estado del Contenedor ==="
    docker ps -a --filter "name=$CONTAINER_NAME" \
        --format "table {{.Status}}\t{{.Ports}}"

    if docker ps -q -f name=$CONTAINER_NAME | grep -q .; then
        echo ""
        echo "=== Consumo de Recursos ==="
        docker stats $CONTAINER_NAME --no-stream \
            --format "table {{.MemUsage}}\t{{.MemPerc}}\t{{.CPUPerc}}"

        echo ""
        echo "=== Configuración SQL Server ==="
        docker exec $CONTAINER_NAME /opt/mssql-tools/bin/sqlcmd \
            -S localhost -U sa -P "$SA_PASSWORD" -Q "
SET NOCOUNT ON;
SELECT
    CAST(name AS VARCHAR(35)) AS Setting,
    CAST(value_in_use AS VARCHAR(10)) AS Value
FROM sys.configurations
WHERE name IN (
    'max server memory (MB)',
    'min server memory (MB)',
    'max degree of parallelism',
    'optimize for ad hoc workloads'
)
ORDER BY name;
" 2>/dev/null
    fi
}

show_logs() {
    docker logs $CONTAINER_NAME --tail 50 -f
}

# =============================================================================
# MAIN
# =============================================================================

case "${1:-start}" in
    start)
        start_container
        ;;
    stop)
        stop_container
        ;;
    restart)
        stop_container
        sleep 2
        start_container
        ;;
    status)
        show_status
        ;;
    optimize)
        wait_for_sql && apply_optimizations
        ;;
    logs)
        show_logs
        ;;
    *)
        echo "Uso: $0 {start|stop|restart|status|optimize|logs}"
        exit 1
        ;;
esac
