#!/bin/bash

# Vision Videoke EC2 Setup Script for Amazon Linux
# This script sets up a complete production environment

set -e  # Exit on any error

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

# Logging function
log() {
    echo -e "${GREEN}[$(date +'%Y-%m-%d %H:%M:%S')] $1${NC}"
}

error() {
    echo -e "${RED}[ERROR] $1${NC}"
    exit 1
}

warn() {
    echo -e "${YELLOW}[WARNING] $1${NC}"
}

info() {
    echo -e "${BLUE}[INFO] $1${NC}"
}

# Check if running as root
if [[ $EUID -eq 0 ]]; then
   error "This script should not be run as root. Please run as ec2-user."
fi

log "Starting Vision Videoke EC2 Setup..."

# Update system
log "Updating system packages..."
sudo yum update -y

# Install essential packages
log "Installing essential packages..."
sudo yum groupinstall -y "Development Tools"
sudo yum install -y \
    git \
    curl \
    wget \
    unzip \
    htop \
    nginx \
    certbot \
    python3-certbot-nginx \
    fail2ban \
    firewalld \
    logrotate

# Install Node.js 18 (LTS)
log "Installing Node.js 18..."
curl -fsSL https://rpm.nodesource.com/setup_18.x | sudo bash -
sudo yum install -y nodejs

# Verify Node.js installation
node_version=$(node --version)
npm_version=$(npm --version)
log "Node.js installed: $node_version"
log "npm installed: $npm_version"

# Install PM2 for process management
log "Installing PM2..."
sudo npm install -g pm2

# Install Yarn (optional but recommended)
log "Installing Yarn..."
sudo npm install -g yarn

# Create application directory
log "Creating application directories..."
sudo mkdir -p /var/www/visionvideoke
sudo chown ec2-user:ec2-user /var/www/visionvideoke

# Create logs directory
sudo mkdir -p /var/log/visionvideoke
sudo chown ec2-user:ec2-user /var/log/visionvideoke

# Setup firewall
log "Configuring firewall..."
sudo systemctl start firewalld
sudo systemctl enable firewalld
sudo firewall-cmd --permanent --add-service=http
sudo firewall-cmd --permanent --add-service=https
sudo firewall-cmd --permanent --add-service=ssh
sudo firewall-cmd --permanent --add-port=3000/tcp  # Node.js app
sudo firewall-cmd --reload

# Configure fail2ban
log "Configuring fail2ban..."
sudo systemctl start fail2ban
sudo systemctl enable fail2ban

# Create fail2ban jail for nginx
sudo tee /etc/fail2ban/jail.local > /dev/null <<EOF
[DEFAULT]
bantime = 3600
findtime = 600
maxretry = 5

[sshd]
enabled = true

[nginx-http-auth]
enabled = true

[nginx-limit-req]
enabled = true
EOF

sudo systemctl restart fail2ban

# Setup log rotation
log "Setting up log rotation..."
sudo tee /etc/logrotate.d/visionvideoke > /dev/null <<EOF
/var/log/visionvideoke/*.log {
    daily
    missingok
    rotate 52
    compress
    delaycompress
    notifempty
    create 644 ec2-user ec2-user
    postrotate
        pm2 reload all
    endscript
}
EOF

# Create systemd service for PM2
log "Creating systemd service for PM2..."
sudo env PATH=$PATH:/usr/bin /usr/lib/node_modules/pm2/bin/pm2 startup systemd -u ec2-user --hp /home/ec2-user

# Create environment file template
log "Creating environment template..."
cat > /home/ec2-user/.env.template <<EOF
# Vision Videoke Environment Configuration
NODE_ENV=production
PORT=3000

# API Keys (REQUIRED - Replace with your actual keys)
REACT_APP_OPENAI_API_KEY=your_openai_api_key_here
REACT_APP_UDIO_API_KEY=your_udio_api_key_here
REACT_APP_ELEVENLABS_API_KEY=your_elevenlabs_api_key_here
REACT_APP_VEO_API_KEY=your_veo_api_key_here

# Database Configuration (if using backend)
DATABASE_URL=postgresql://user:password@localhost:5432/visionvideoke

# File Storage (AWS S3)
AWS_ACCESS_KEY_ID=your_aws_access_key
AWS_SECRET_ACCESS_KEY=your_aws_secret_key
AWS_REGION=us-east-1
AWS_S3_BUCKET=visionvideoke-uploads

# Domain Configuration
DOMAIN_NAME=your-domain.com
SSL_EMAIL=admin@your-domain.com

# Security
JWT_SECRET=your_jwt_secret_here
ENCRYPTION_KEY=your_encryption_key_here

# Payment Processing (Stripe)
STRIPE_PUBLISHABLE_KEY=pk_live_your_stripe_key
STRIPE_SECRET_KEY=sk_live_your_stripe_secret

# Monitoring
SENTRY_DSN=your_sentry_dsn_here
EOF

# Create deployment script
log "Creating deployment script..."
cat > /home/ec2-user/deploy-app.sh <<'EOF'
#!/bin/bash

# Vision Videoke Deployment Script
set -e

APP_DIR="/var/www/visionvideoke"
BACKUP_DIR="/var/backups/visionvideoke"
LOG_FILE="/var/log/visionvideoke/deploy.log"

log() {
    echo "[$(date +'%Y-%m-%d %H:%M:%S')] $1" | tee -a $LOG_FILE
}

# Create backup
log "Creating backup..."
mkdir -p $BACKUP_DIR
if [ -d "$APP_DIR" ]; then
    tar -czf "$BACKUP_DIR/backup-$(date +%Y%m%d-%H%M%S).tar.gz" -C "$APP_DIR" . || true
fi

# Deploy application
log "Deploying application..."
cd $APP_DIR

# Install dependencies
log "Installing dependencies..."
npm ci --production

# Build application
log "Building application..."
npm run build

# Restart PM2
log "Restarting application..."
pm2 restart all || pm2 start ecosystem.config.js

# Reload nginx
log "Reloading nginx..."
sudo nginx -t && sudo systemctl reload nginx

log "Deployment completed successfully!"
EOF

chmod +x /home/ec2-user/deploy-app.sh

# Create PM2 ecosystem file template
log "Creating PM2 ecosystem template..."
cat > /home/ec2-user/ecosystem.config.js <<EOF
module.exports = {
  apps: [{
    name: 'visionvideoke',
    script: 'npm',
    args: 'start',
    cwd: '/var/www/visionvideoke',
    instances: 'max',
    exec_mode: 'cluster',
    env: {
      NODE_ENV: 'production',
      PORT: 3000
    },
    error_file: '/var/log/visionvideoke/error.log',
    out_file: '/var/log/visionvideoke/out.log',
    log_file: '/var/log/visionvideoke/combined.log',
    time: true,
    max_memory_restart: '1G',
    node_args: '--max-old-space-size=1024'
  }]
};
EOF

# Create health check script
log "Creating health check script..."
cat > /home/ec2-user/health-check.sh <<'EOF'
#!/bin/bash

# Health check script for Vision Videoke
APP_URL="http://localhost:3000"
LOG_FILE="/var/log/visionvideoke/health.log"

check_health() {
    local timestamp=$(date +'%Y-%m-%d %H:%M:%S')
    
    # Check if app is responding
    if curl -f -s "$APP_URL" > /dev/null; then
        echo "[$timestamp] Health check PASSED" >> $LOG_FILE
        return 0
    else
        echo "[$timestamp] Health check FAILED" >> $LOG_FILE
        return 1
    fi
}

# Run health check
if ! check_health; then
    echo "Application is down, attempting restart..."
    pm2 restart visionvideoke
    sleep 10
    
    if check_health; then
        echo "Application restarted successfully"
    else
        echo "Application restart failed, sending alert..."
        # Add your alerting mechanism here (email, Slack, etc.)
    fi
fi
EOF

chmod +x /home/ec2-user/health-check.sh

# Add health check to crontab
log "Setting up health check cron job..."
(crontab -l 2>/dev/null; echo "*/5 * * * * /home/ec2-user/health-check.sh") | crontab -

# Create SSL setup script
log "Creating SSL setup script..."
cat > /home/ec2-user/setup-ssl.sh <<'EOF'
#!/bin/bash

# SSL Setup Script for Vision Videoke
set -e

if [ -z "$1" ]; then
    echo "Usage: $0 <domain-name> [email]"
    echo "Example: $0 visionvideoke.com admin@visionvideoke.com"
    exit 1
fi

DOMAIN=$1
EMAIL=${2:-admin@$DOMAIN}

echo "Setting up SSL for domain: $DOMAIN"
echo "Email: $EMAIL"

# Stop nginx temporarily
sudo systemctl stop nginx

# Get SSL certificate
sudo certbot certonly --standalone -d $DOMAIN --email $EMAIL --agree-tos --non-interactive

# Start nginx
sudo systemctl start nginx

# Setup auto-renewal
echo "0 12 * * * /usr/bin/certbot renew --quiet" | sudo crontab -

echo "SSL setup completed for $DOMAIN"
EOF

chmod +x /home/ec2-user/setup-ssl.sh

# Create monitoring script
log "Creating monitoring script..."
cat > /home/ec2-user/monitor.sh <<'EOF'
#!/bin/bash

# System monitoring script for Vision Videoke
LOG_FILE="/var/log/visionvideoke/monitor.log"

log_metric() {
    echo "[$(date +'%Y-%m-%d %H:%M:%S')] $1" >> $LOG_FILE
}

# CPU Usage
CPU_USAGE=$(top -bn1 | grep "Cpu(s)" | awk '{print $2}' | awk -F'%' '{print $1}')
log_metric "CPU Usage: ${CPU_USAGE}%"

# Memory Usage
MEMORY_USAGE=$(free | grep Mem | awk '{printf("%.2f", $3/$2 * 100.0)}')
log_metric "Memory Usage: ${MEMORY_USAGE}%"

# Disk Usage
DISK_USAGE=$(df -h / | awk 'NR==2{printf "%s", $5}')
log_metric "Disk Usage: $DISK_USAGE"

# Application Status
if pm2 list | grep -q "online"; then
    log_metric "Application Status: ONLINE"
else
    log_metric "Application Status: OFFLINE"
fi

# Nginx Status
if systemctl is-active --quiet nginx; then
    log_metric "Nginx Status: ACTIVE"
else
    log_metric "Nginx Status: INACTIVE"
fi
EOF

chmod +x /home/ec2-user/monitor.sh

# Add monitoring to crontab
(crontab -l 2>/dev/null; echo "*/10 * * * * /home/ec2-user/monitor.sh") | crontab -

# Create backup script
log "Creating backup script..."
cat > /home/ec2-user/backup.sh <<'EOF'
#!/bin/bash

# Backup script for Vision Videoke
BACKUP_DIR="/var/backups/visionvideoke"
APP_DIR="/var/www/visionvideoke"
LOG_FILE="/var/log/visionvideoke/backup.log"
RETENTION_DAYS=30

log() {
    echo "[$(date +'%Y-%m-%d %H:%M:%S')] $1" | tee -a $LOG_FILE
}

# Create backup directory
mkdir -p $BACKUP_DIR

# Create backup
BACKUP_NAME="visionvideoke-backup-$(date +%Y%m%d-%H%M%S).tar.gz"
log "Creating backup: $BACKUP_NAME"

tar -czf "$BACKUP_DIR/$BACKUP_NAME" \
    -C "$APP_DIR" . \
    --exclude=node_modules \
    --exclude=.git \
    --exclude=dist

# Cleanup old backups
log "Cleaning up old backups (older than $RETENTION_DAYS days)"
find $BACKUP_DIR -name "*.tar.gz" -mtime +$RETENTION_DAYS -delete

log "Backup completed: $BACKUP_NAME"
EOF

chmod +x /home/ec2-user/backup.sh

# Add backup to crontab (daily at 2 AM)
(crontab -l 2>/dev/null; echo "0 2 * * * /home/ec2-user/backup.sh") | crontab -

# Set proper permissions
log "Setting proper permissions..."
sudo chown -R ec2-user:ec2-user /home/ec2-user/
chmod 600 /home/ec2-user/.env.template

log "EC2 setup completed successfully!"
log ""
log "Next steps:"
log "1. Copy your application files to /var/www/visionvideoke"
log "2. Configure environment variables in /home/ec2-user/.env.template"
log "3. Run nginx configuration script"
log "4. Setup SSL with ./setup-ssl.sh your-domain.com"
log "5. Deploy your application with ./deploy-app.sh"
log ""
log "Useful commands:"
log "- pm2 status          # Check application status"
log "- pm2 logs            # View application logs"
log "- pm2 restart all     # Restart application"
log "- sudo nginx -t       # Test nginx configuration"
log "- sudo systemctl status nginx  # Check nginx status"
log ""
log "Log files location: /var/log/visionvideoke/"
log "Backup location: /var/backups/visionvideoke/"

