package devopsmodules

import (
	"rubric/utils"
)

var NginxModule = Module{
	Key:         "nginx",
	Aliases:     []string{"n", "web", "proxy", "haproxy"},
	Title:       "Nginx и балансировка нагрузки",
	Description: "Конфигурация, virtual hosts, reverse proxy, SSL/TLS, балансировка, HAProxy",
	Run:         showNginx,
}

func showNginx() {
	utils.Header("DevOps — Nginx и балансировка нагрузки")

	utils.Section("Основы Nginx")
	utils.Code(`# Установка:
apt install nginx          # Debian/Ubuntu
dnf install nginx          # RHEL/Fedora

systemctl enable --now nginx
nginx -t                   # проверить конфигурацию
nginx -s reload            # перезагрузить конфиг
nginx -s stop              # остановить

# Структура конфигурации:
/etc/nginx/
├── nginx.conf             # главный файл
├── conf.d/                # дополнительные конфиги (*.conf)
├── sites-available/       # доступные виртуальные хосты
├── sites-enabled/         # включённые (симлинки)
├── snippets/              # переиспользуемые блоки
└── mime.types             # MIME-типы`)

	utils.Section("nginx.conf — основной конфиг")
	utils.Code(`user nginx;
worker_processes auto;           # = количество CPU
error_log /var/log/nginx/error.log warn;
pid /run/nginx.pid;

events {
    worker_connections 1024;     # соединений на воркер
    multi_accept on;
    use epoll;                   # Linux event model
}

http {
    include       /etc/nginx/mime.types;
    default_type  application/octet-stream;

    # Логи:
    log_format main '$remote_addr - $remote_user [$time_local] '
                    '"$request" $status $body_bytes_sent '
                    '"$http_referer" "$http_user_agent" '
                    'rt=$request_time uct=$upstream_connect_time';
    access_log /var/log/nginx/access.log main;

    # Производительность:
    sendfile        on;
    tcp_nopush      on;
    tcp_nodelay     on;
    keepalive_timeout 65;
    gzip on;
    gzip_types text/plain text/css application/json application/javascript;

    # Безопасность:
    server_tokens off;           # скрыть версию nginx
    client_max_body_size 10M;
    client_body_timeout 12s;
    client_header_timeout 12s;

    include /etc/nginx/conf.d/*.conf;
}`)

	utils.Section("Virtual Hosts (Server Blocks)")
	utils.Code(`# /etc/nginx/conf.d/example.com.conf

# Статический сайт:
server {
    listen 80;
    server_name example.com www.example.com;
    root /var/www/example.com;
    index index.html;

    location / {
        try_files $uri $uri/ =404;
    }

    location ~* \.(jpg|jpeg|png|gif|ico|css|js)$ {
        expires 30d;
        add_header Cache-Control "public, immutable";
    }

    # Перенаправление на HTTPS:
    return 301 https://$host$request_uri;
}

# HTTPS:
server {
    listen 443 ssl http2;
    server_name example.com www.example.com;
    root /var/www/example.com;

    ssl_certificate     /etc/ssl/certs/example.com.crt;
    ssl_certificate_key /etc/ssl/private/example.com.key;

    # Современные настройки TLS:
    ssl_protocols TLSv1.2 TLSv1.3;
    ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:...;
    ssl_prefer_server_ciphers off;
    ssl_session_cache shared:SSL:10m;
    ssl_session_timeout 10m;
    ssl_stapling on;
    ssl_stapling_verify on;

    # HSTS:
    add_header Strict-Transport-Security "max-age=63072000" always;
    add_header X-Frame-Options DENY;
    add_header X-Content-Type-Options nosniff;

    location / {
        try_files $uri $uri/ =404;
    }
}`)

	utils.Section("Reverse Proxy")
	utils.Code(`# Проксирование к бэкенду:
server {
    listen 443 ssl http2;
    server_name api.example.com;

    ssl_certificate     /etc/letsencrypt/live/api.example.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/api.example.com/privkey.pem;

    location / {
        proxy_pass         http://localhost:8000;
        proxy_http_version 1.1;
        proxy_set_header   Upgrade $http_upgrade;
        proxy_set_header   Connection 'upgrade';   # WebSocket
        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;

        proxy_connect_timeout 30s;
        proxy_send_timeout    30s;
        proxy_read_timeout    30s;
    }

    # Кэширование статики:
    location /static/ {
        proxy_pass http://localhost:8000/static/;
        proxy_cache_valid 200 1d;
        expires 1d;
    }
}`)

	utils.Section("Балансировка нагрузки")
	utils.Code(`# upstream — группа серверов:
upstream myapp {
    least_conn;          # least connections (или round_robin, ip_hash)

    server backend1:8000 weight=3;    # 3x больше запросов
    server backend2:8000 weight=1;
    server backend3:8000;
    server backend4:8000 backup;      # только при недоступности остальных

    keepalive 32;                     # keepalive соединения
}

upstream myapp {
    ip_hash;             # один клиент → один бэкенд (sticky sessions)
    server backend1:8000;
    server backend2:8000;
}

server {
    listen 80;
    location / {
        proxy_pass http://myapp;
        health_check;    # nginx plus или модуль
    }
}

# Алгоритмы балансировки:
# round_robin   — по очереди (по умолчанию)
# least_conn    — к серверу с наименьшим числом соединений
# ip_hash       — по IP клиента (sticky sessions)
# hash $var     — по произвольной переменной
# random        — случайно`)

	utils.Section("Настройки производительности и безопасности")
	utils.Code(`# Rate limiting — ограничение запросов:
http {
    limit_req_zone $binary_remote_addr zone=api:10m rate=10r/s;
    limit_conn_zone $binary_remote_addr zone=conn:10m;
}

server {
    location /api/ {
        limit_req zone=api burst=20 nodelay;
        limit_conn conn 10;
        proxy_pass http://backend;
    }

    # Защита от DDoS:
    location /login {
        limit_req zone=api rate=1r/s burst=5;
        proxy_pass http://backend;
    }
}

# Аутентификация Basic Auth:
location /admin {
    auth_basic "Admin Area";
    auth_basic_user_file /etc/nginx/.htpasswd;
    proxy_pass http://backend;
}
# htpasswd -c /etc/nginx/.htpasswd admin

# Блокировка по IP:
location /api {
    deny  192.168.1.100;
    allow 192.168.1.0/24;
    deny  all;
    proxy_pass http://backend;
}

# Кэширование прокси:
proxy_cache_path /var/cache/nginx levels=1:2 keys_zone=my_cache:10m
                 max_size=1g inactive=60m;
server {
    location / {
        proxy_cache my_cache;
        proxy_cache_valid 200 10m;
        proxy_cache_use_stale error timeout updating;
        add_header X-Cache-Status $upstream_cache_status;
        proxy_pass http://backend;
    }
}`)

	utils.Section("Let's Encrypt — бесплатные сертификаты")
	utils.Code(`# Установка certbot:
apt install certbot python3-certbot-nginx

# Получить и настроить сертификат:
certbot --nginx -d example.com -d www.example.com

# Только получить сертификат (без правки nginx.conf):
certbot certonly --nginx -d example.com

# Обновление (автоматически через systemd timer или cron):
certbot renew --dry-run    # тест
certbot renew              # обновить просроченные

# Принудительное обновление:
certbot renew --force-renewal

# Wildcard сертификат (через DNS challenge):
certbot certonly --manual \
  -d "*.example.com" \
  --preferred-challenges dns`)

	utils.Section("HAProxy — продвинутая балансировка")
	utils.Code(`# HAProxy — специализированный балансировщик нагрузки.
# Лучше nginx для TCP/L4 балансировки.
# Богатые возможности health check и ACL.

# /etc/haproxy/haproxy.cfg:
global
    maxconn 50000
    log /dev/log local0
    stats socket /run/haproxy/admin.sock mode 660 level admin

defaults
    log     global
    mode    http
    option  httplog
    option  dontlognull
    timeout connect 5s
    timeout client  30s
    timeout server  30s
    option  forwardfor
    option  http-server-close

frontend http_front
    bind *:80
    redirect scheme https unless { ssl_fc }

frontend https_front
    bind *:443 ssl crt /etc/ssl/certs/example.pem
    default_backend app_back

    # ACL-маршрутизация:
    acl is_api path_beg /api/
    use_backend api_back if is_api

backend app_back
    balance roundrobin
    option httpchk GET /health
    server web1 192.168.1.10:8000 check weight 2
    server web2 192.168.1.11:8000 check weight 1
    server web3 192.168.1.12:8000 check backup

backend api_back
    balance leastconn
    timeout server 60s
    server api1 192.168.1.20:8080 check
    server api2 192.168.1.21:8080 check

# Статистика:
frontend stats
    bind *:8404
    stats enable
    stats uri /stats
    stats refresh 10s
    stats auth admin:secret`)

	utils.Footer()
}
