#!/bin/bash
set -e

SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
SECRETS_DIR="${SCRIPT_DIR}/secrets"

# Colors for output
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
NC='\033[0m' # No Color

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

usage() {
    echo "Usage: $0 <command>"
    echo ""
    echo "Commands:"
    echo "  init          Initialize secrets directory with AppRole credentials"
    echo "  start         Start the application (migrations run automatically)"
    echo "  stop          Stop the application"
    echo "  restart       Safe restart (down + up, preserves startup order)"
    echo "  logs          View application logs"
    echo "  rebuild       Rebuild and restart (migrations run automatically)"
    echo "  rebuild --no-cache  Force full rebuild without Docker cache"
    echo ""
    echo "WARNING: Do not use 'docker compose restart <service>' directly!"
    echo "         This breaks service dependencies. Always use './setup.sh restart'"
    echo ""
    echo "Environment variables (for init):"
    echo "  VAULT_APP_ROLE_ID              AppRole ID for nexus app runtime"
    echo "  VAULT_APP_SECRET_ID            AppRole Secret ID for nexus app runtime"
    echo "  VAULT_MIGRATE_ROLE_ID          AppRole ID for nexus migrations"
    echo "  VAULT_MIGRATE_SECRET_ID        AppRole Secret ID for nexus migrations"
    echo "  VAULT_KRATOS_APP_ROLE_ID       AppRole ID for kratos runtime"
    echo "  VAULT_KRATOS_APP_SECRET_ID     AppRole Secret ID for kratos runtime"
    echo "  VAULT_KRATOS_MIGRATE_ROLE_ID   AppRole ID for kratos migrations"
    echo "  VAULT_KRATOS_MIGRATE_SECRET_ID AppRole Secret ID for kratos migrations"
    echo "  VAULT_OATHKEEPER_ROLE_ID       AppRole ID for oathkeeper runtime"
    echo "  VAULT_OATHKEEPER_SECRET_ID     AppRole Secret ID for oathkeeper runtime"
}

init_secrets() {
    log_info "Initializing secrets directory..."

    # Create directories for all services
    mkdir -p "${SECRETS_DIR}/app" "${SECRETS_DIR}/migrate"
    mkdir -p "${SECRETS_DIR}/kratos-app" "${SECRETS_DIR}/kratos-migrate"
    mkdir -p "${SECRETS_DIR}/oathkeeper"
    mkdir -p "${SCRIPT_DIR}/run/app" "${SCRIPT_DIR}/run/migrate"
    mkdir -p "${SCRIPT_DIR}/run/kratos" "${SCRIPT_DIR}/run/kratos-migrate"
    mkdir -p "${SCRIPT_DIR}/run/oathkeeper"

    # Check for required nexus environment variables
    if [ -z "$VAULT_APP_ROLE_ID" ] || [ -z "$VAULT_APP_SECRET_ID" ]; then
        log_error "VAULT_APP_ROLE_ID and VAULT_APP_SECRET_ID must be set"
        exit 1
    fi

    if [ -z "$VAULT_MIGRATE_ROLE_ID" ] || [ -z "$VAULT_MIGRATE_SECRET_ID" ]; then
        log_error "VAULT_MIGRATE_ROLE_ID and VAULT_MIGRATE_SECRET_ID must be set"
        exit 1
    fi

    # Check for required kratos environment variables
    if [ -z "$VAULT_KRATOS_APP_ROLE_ID" ] || [ -z "$VAULT_KRATOS_APP_SECRET_ID" ]; then
        log_error "VAULT_KRATOS_APP_ROLE_ID and VAULT_KRATOS_APP_SECRET_ID must be set"
        exit 1
    fi

    if [ -z "$VAULT_KRATOS_MIGRATE_ROLE_ID" ] || [ -z "$VAULT_KRATOS_MIGRATE_SECRET_ID" ]; then
        log_error "VAULT_KRATOS_MIGRATE_ROLE_ID and VAULT_KRATOS_MIGRATE_SECRET_ID must be set"
        exit 1
    fi

    # Check for required oathkeeper environment variables
    if [ -z "$VAULT_OATHKEEPER_ROLE_ID" ] || [ -z "$VAULT_OATHKEEPER_SECRET_ID" ]; then
        log_error "VAULT_OATHKEEPER_ROLE_ID and VAULT_OATHKEEPER_SECRET_ID must be set"
        exit 1
    fi

    # Write nexus app credentials (644 for container read access)
    echo -n "$VAULT_APP_ROLE_ID" > "${SECRETS_DIR}/app/role-id"
    echo -n "$VAULT_APP_SECRET_ID" > "${SECRETS_DIR}/app/secret-id"
    chmod 644 "${SECRETS_DIR}/app/role-id" "${SECRETS_DIR}/app/secret-id"
    log_info "Nexus app credentials written to ${SECRETS_DIR}/app/"

    # Write nexus migrate credentials (644 for container read access)
    echo -n "$VAULT_MIGRATE_ROLE_ID" > "${SECRETS_DIR}/migrate/role-id"
    echo -n "$VAULT_MIGRATE_SECRET_ID" > "${SECRETS_DIR}/migrate/secret-id"
    chmod 644 "${SECRETS_DIR}/migrate/role-id" "${SECRETS_DIR}/migrate/secret-id"
    log_info "Nexus migrate credentials written to ${SECRETS_DIR}/migrate/"

    # Write kratos app credentials (644 for container read access)
    echo -n "$VAULT_KRATOS_APP_ROLE_ID" > "${SECRETS_DIR}/kratos-app/role-id"
    echo -n "$VAULT_KRATOS_APP_SECRET_ID" > "${SECRETS_DIR}/kratos-app/secret-id"
    chmod 644 "${SECRETS_DIR}/kratos-app/role-id" "${SECRETS_DIR}/kratos-app/secret-id"
    log_info "Kratos app credentials written to ${SECRETS_DIR}/kratos-app/"

    # Write kratos migrate credentials (644 for container read access)
    echo -n "$VAULT_KRATOS_MIGRATE_ROLE_ID" > "${SECRETS_DIR}/kratos-migrate/role-id"
    echo -n "$VAULT_KRATOS_MIGRATE_SECRET_ID" > "${SECRETS_DIR}/kratos-migrate/secret-id"
    chmod 644 "${SECRETS_DIR}/kratos-migrate/role-id" "${SECRETS_DIR}/kratos-migrate/secret-id"
    log_info "Kratos migrate credentials written to ${SECRETS_DIR}/kratos-migrate/"

    # Write oathkeeper credentials (644 for container read access)
    echo -n "$VAULT_OATHKEEPER_ROLE_ID" > "${SECRETS_DIR}/oathkeeper/role-id"
    echo -n "$VAULT_OATHKEEPER_SECRET_ID" > "${SECRETS_DIR}/oathkeeper/secret-id"
    chmod 644 "${SECRETS_DIR}/oathkeeper/role-id" "${SECRETS_DIR}/oathkeeper/secret-id"
    log_info "Oathkeeper credentials written to ${SECRETS_DIR}/oathkeeper/"

    log_info "All secrets initialized successfully!"
}

start_app() {
    log_info "Starting application..."

    if [ ! -f "${SECRETS_DIR}/app/role-id" ]; then
        log_error "Nexus secrets not initialized. Run '$0 init' first."
        exit 1
    fi

    if [ ! -f "${SECRETS_DIR}/kratos-app/role-id" ]; then
        log_error "Kratos secrets not initialized. Run '$0 init' first."
        exit 1
    fi

    if [ ! -f "${SECRETS_DIR}/oathkeeper/role-id" ]; then
        log_error "Oathkeeper secrets not initialized. Run '$0 init' first."
        exit 1
    fi

    # Start all services (migrations run automatically before app)
    docker compose up -d
    log_info "Application started!"
    log_info "Health checks:"
    log_info "  Nexus:      curl http://localhost:5050/health/ready"
    log_info "  Kratos:     curl http://localhost:6050/health/alive"
    log_info "  Oathkeeper: curl http://localhost:7250/health/alive"
    log_info "  Frontend:   curl http://localhost:5000/"
}

stop_app() {
    log_info "Stopping application..."
    docker compose down
    log_info "Application stopped!"
}

restart_app() {
    log_info "Restarting application (safe restart)..."

    if [ ! -f "${SECRETS_DIR}/app/role-id" ]; then
        log_error "Nexus secrets not initialized. Run '$0 init' first."
        exit 1
    fi

    # Safe restart: down then up preserves dependency order
    docker compose down
    docker compose up -d

    log_info "Application restarted!"
    log_info "Health checks:"
    log_info "  Nexus:      curl http://localhost:5050/health/ready"
    log_info "  Kratos:     curl http://localhost:6050/health/alive"
    log_info "  Oathkeeper: curl http://localhost:7250/health/alive"
    log_info "  Frontend:   curl http://localhost:5000/"
}

rebuild_app() {
    local no_cache="${1:-}"

    if [ "$no_cache" = "--no-cache" ]; then
        log_info "Rebuilding without cache and restarting application..."
    else
        log_info "Rebuilding and restarting application..."
    fi

    if [ ! -f "${SECRETS_DIR}/app/role-id" ]; then
        log_error "Nexus secrets not initialized. Run '$0 init' first."
        exit 1
    fi

    if [ ! -f "${SECRETS_DIR}/kratos-app/role-id" ]; then
        log_error "Kratos secrets not initialized. Run '$0 init' first."
        exit 1
    fi

    if [ ! -f "${SECRETS_DIR}/oathkeeper/role-id" ]; then
        log_error "Oathkeeper secrets not initialized. Run '$0 init' first."
        exit 1
    fi

    # Pull latest code
    git pull

    # Rebuild and restart (migrations run automatically)
    if [ "$no_cache" = "--no-cache" ]; then
        docker compose build --no-cache
        docker compose up -d
    else
        docker compose up -d --build
    fi

    log_info "Application rebuilt and started!"
    log_info "Health checks:"
    log_info "  Nexus:      curl http://localhost:5050/health/ready"
    log_info "  Kratos:     curl http://localhost:6050/health/alive"
    log_info "  Oathkeeper: curl http://localhost:7250/health/alive"
    log_info "  Frontend:   curl http://localhost:5000/"
}

view_logs() {
    local service="${1:-}"
    if [ -z "$service" ]; then
        docker compose logs -f nexus kratos oathkeeper frontend
    else
        docker compose logs -f "$service"
    fi
}

# Main
case "${1:-}" in
    init)
        init_secrets
        ;;
    start)
        start_app
        ;;
    stop)
        stop_app
        ;;
    restart)
        restart_app
        ;;
    rebuild)
        rebuild_app "${2:-}"
        ;;
    logs)
        view_logs
        ;;
    *)
        usage
        exit 1
        ;;
esac
