#!/bin/bash

# --------------------------------------------------------
# .NET App Setup Script � Generates Deploy/Nginx/Systemd
# --------------------------------------------------------

# Step 1: Get inputs
read -p "What is the name of your app? " appName

echo
echo "Select the environment:"
select env in "dev" "qa" "uat" "prod"; do
  case $REPLY in
    1|2|3|4)
      break
      ;;
    *)
      echo "[ERROR] Invalid selection. Please choose 1, 2, 3 or 4."
      ;;
  esac
done


read -p "Enter the domain (e.g. app.example.com): " domain
read -p "Enter the Kestrel HTTP port (e.g. 5000): " kestrelPort
read -p "Enter the DLL filename (e.g. MyApp.dll): " dllFile
read -p "Enter the username that will own the app folder (e.g. deploy): " deployUser

# Step 2: Paths & files
basePath="/var/www/${appName}/${env}"
artifactDir="${basePath}/artifact"
appDir="${basePath}/app"
scriptDir="${basePath}/script"
deployScript="${scriptDir}/deploy.sh"
serviceName="${appName}-${env}.service"
serviceFile="/etc/systemd/system/${serviceName}"
nginxSite="/etc/nginx/sites-available/${appName}-${env}"
nginxLink="/etc/nginx/sites-enabled/${appName}-${env}"

# Step 3: Confirm setup
echo
echo "----------------------------------------------"
echo "App Name      : $appName"
echo "Environment   : $env"
echo "Domain        : $domain"
echo "Kestrel Port  : $kestrelPort"
echo "DLL File      : $dllFile"
echo "Target User   : $deployUser"
echo "----------------------------------------------"
read -p "Proceed with setup? (y/n): " confirm

if [[ "$confirm" =~ ^[Yy]$ ]]; then
  echo "[INFO] Creating directories..."
  mkdir -p "$artifactDir" "$appDir" "$scriptDir"
  mkdir -p "$scriptDir/logs"

  # --- Deploy Script -------------------------------
  echo "[INFO] Generating deploy script..."
  cat <<EOF > "$deployScript"
#!/bin/bash

appName="${appName}"
env="${env}"
SERVICE_NAME="\${appName}-\${env}.service"
basePath="/var/www/\${appName}/\${env}"
artifactDir="\${basePath}/artifact"
appDir="\${basePath}/app"

# Define log file
logFile="\$basePath/script/logs/deploy-\$(date +'%Y-%m-%d_%H-%M-%S').log"
ln -sf "\$logFile" "\$basePath/script/logs/latest.log"
exec > >(tee -a "\$logFile") 2>&1

echo "[\$(date)] ? Logging to \$logFile"

echo "[\$(date)] Starting deployment for \$SERVICE_NAME..."

artifactFile=\$(find "\$artifactDir" -maxdepth 1 -type f -iname "*.zip" | head -n 1)

if [[ -z "\$artifactFile" ]]; then
  echo "[\$(date)] [ERROR] No .zip file found in \$artifactDir"
  exit 1
fi

tempDir=\$(mktemp -d)
echo "[\$(date)] Extracting to: \$tempDir"
unzip -o "\$artifactFile" -d "\$tempDir"
if [[ \$? -ne 0 ]]; then
  echo "[\$(date)] [ERROR] Failed to unzip artifact"
  exit 2
fi

# Detect and flatten if single nested folder
firstItem=\$(find "\$tempDir" -mindepth 1 -maxdepth 1 | head -n 1)
if [[ -d "\$firstItem" ]] && [[ \$(find "\$tempDir" -mindepth 1 -maxdepth 1 | wc -l) -eq 1 ]]; then
  echo "[\$(date)] Flattening nested folder: \$firstItem"
  tempDir="\$firstItem"
fi

echo "[\$(date)] Syncing contents to \$appDir"
rm -rf "\$appDir"/*
cp -r "\$tempDir"/* "\$appDir"/
rm -rf "\$tempDir"

echo "[\$(date)] Reloading systemd..."
sudo systemctl daemon-reload || exit 3

echo "[\$(date)] Restarting \$SERVICE_NAME..."
sudo systemctl restart "\$SERVICE_NAME" || exit 4

echo "[\$(date)] [SUCCESS] Deployment successful."
EOF

  chmod +x "$deployScript"

  # --- systemd Unit -------------------------------
  echo "[INFO] Creating systemd service..."
  sudo tee "$serviceFile" > /dev/null <<EOF
[Unit]
Description=${appName} ${env} Service
After=network.target

[Service]
WorkingDirectory=${appDir}
ExecStart=/usr/bin/dotnet ${appDir}/${dllFile}
Restart=always
RestartSec=10
SyslogIdentifier=${appName}-${env}
User=www-data
Environment=ASPNETCORE_ENVIRONMENT=Production
Environment=DOTNET_PRINT_TELEMETRY_MESSAGE=false

[Install]
WantedBy=multi-user.target
EOF

  sudo systemctl daemon-reload
  sudo systemctl enable "$serviceName"

  # --- Nginx Config -------------------------------
  echo "[INFO] Creating Nginx config..."
  sudo tee "$nginxSite" > /dev/null <<EOF
server {
    listen 80;
    server_name ${domain};

    proxy_buffer_size       16k;
    proxy_buffers           8 16k;
    proxy_busy_buffers_size 32k;

    large_client_header_buffers 4 16k;

    location / {
        proxy_pass         http://localhost:${kestrelPort};
        proxy_http_version 1.1;
        proxy_set_header   Upgrade \$http_upgrade;
        proxy_set_header   Connection keep-alive;
        proxy_set_header   Host \$host;
        proxy_set_header   X-Real-IP \$remote_addr;
        proxy_set_header   X-Forwarded-For \$proxy_add_x_forwarded_for;
        proxy_set_header   X-Forwarded-Proto \$scheme;
        proxy_cache_bypass \$http_upgrade;
    }
}
EOF

  sudo ln -sf "$nginxSite" "$nginxLink"
  sudo nginx -t && sudo systemctl reload nginx
  if id "$deployUser" &>/dev/null; then
    sudo chown -R "$deployUser":"$deployUser" "/var/www/${appName}"
    echo "[INFO] Ownership of /var/www/${appName} set to $deployUser"
  else
    echo "[WARNING] User '$deployUser' does not exist. Skipping chown."
  fi
  # Optional SSL
  echo
  read -p "Would you like to enable HTTPS with Certbot for $domain? (y/n): " enableSSL
  if [[ "$enableSSL" =~ ^[Yy]$ ]]; then
    read -p "Enter your email for Let's Encrypt notifications: " sslEmail
    sudo certbot --nginx -d "$domain" --non-interactive --agree-tos -m "$sslEmail" || {
      echo "[WARNING] [ERROR] Certbot failed. Check DNS and firewall settings."
    }
  else
    echo "[INFO] Skipping SSL setup."
  fi

  echo
  echo
  echo "[SUCCESS] Setup complete!"
  echo "� Deployment script: $deployScript"
  echo "� Service: $serviceName"
  echo "� Domain: http://$domain"
  echo "� User: $deployUser"
else
  echo "[CANCELLED] Setup cancelled."
  exit 1
fi
