package linuxmodules

import (
	"fmt"
	"rubric/utils"
)

var BootModule = Module{
	Key:         "boot",
	Aliases:     []string{"bo", "systemd", "grub", "загрузка"},
	Title:       "Загрузка системы и systemd",
	Description: "Темы 33–35, 41: GRUB, systemd, юниты, управление сервисами",
	Run:         showBoot,
}

func showBoot() {
	utils.Header("Linux — Загрузка системы и systemd")

	// ─── 33. GRUB ─────────────────────────────────────────────────
	utils.Section("33. Загрузчик GRUB")

	utils.Println("Процесс загрузки Linux:")
	utils.Code(`BIOS/UEFI → MBR/GPT → GRUB → Ядро (vmlinuz) → initrd/initramfs → /sbin/init (systemd) → Сервисы → Пользователь

BIOS/UEFI   — инициализация железа, поиск загрузочного устройства
MBR/GPT     — первый сектор диска, указывает где GRUB
GRUB        — загрузчик, выбор ядра/ОС
vmlinuz     — сжатое ядро Linux
initramfs   — временная корневая ФС в памяти (для монтирования /)
systemd     — PID 1, запускает все сервисы`)

	utils.Println(utils.ColorBold + "GRUB — конфигурация:" + utils.ColorReset)
	utils.Code(`# Основные файлы:
/boot/grub/grub.cfg         — итоговая конфигурация (не редактировать!)
/etc/grub.d/                — скрипты генерации конфига
/etc/default/grub           — настройки

# Редактировать настройки:
sudo nano /etc/default/grub

# Ключевые параметры /etc/default/grub:
GRUB_DEFAULT=0              # пункт меню по умолчанию (0 = первый)
GRUB_TIMEOUT=5              # таймаут выбора (сек)
GRUB_CMDLINE_LINUX=""       # параметры ядра для всех записей
GRUB_CMDLINE_LINUX_DEFAULT="quiet splash"  # для обычной загрузки

# Применить изменения:
sudo update-grub            # Debian/Ubuntu
sudo grub2-mkconfig -o /boot/grub2/grub.cfg  # RHEL/Fedora`)

	utils.Println(utils.ColorBold + "GRUB — установка и восстановление:" + utils.ColorReset)
	utils.Code(`# Установить GRUB на диск:
sudo grub-install /dev/sda          # Debian/Ubuntu
sudo grub2-install /dev/sda         # RHEL/Fedora

# Восстановление GRUB через LiveCD:
mount /dev/sda2 /mnt                # корневой раздел
mount /dev/sda1 /mnt/boot/efi       # EFI раздел (UEFI)
mount --bind /dev /mnt/dev
mount --bind /proc /mnt/proc
mount --bind /sys /mnt/sys
chroot /mnt
grub-install /dev/sda
update-grub
exit; reboot`)

	utils.Println(utils.ColorBold + "Параметры ядра при загрузке:" + utils.ColorReset)
	utils.Code(`# Нажать 'e' в меню GRUB для редактирования записи.
# Найти строку linux/linuxefi и добавить параметры в конец:

ro quiet splash        — стандартная загрузка
rw single              — однопользовательский режим (recovery)
init=/bin/bash         — минимальный shell (без systemd)
nomodeset              — без KMS (проблемы с видео)
rd.break               — остановить в initramfs (RHEL)
systemd.unit=rescue.target  — аварийный режим`)

	// ─── 34. systemd ──────────────────────────────────────────────
	utils.Section("34. Система инициализации — systemd")

	utils.Println("systemd — PID 1. Управляет всеми сервисами, монтированием, логами.")
	fmt.Println()
	utils.Println(utils.ColorBold + "Юниты (Units):" + utils.ColorReset)
	utils.Code(`Юнит — объект управления systemd.
Типы юнитов:
.service  — сервис (nginx.service, sshd.service)
.socket   — сокет (активация по запросу)
.target   — группа юнитов (graphical.target = GUI)
.timer    — планировщик (альтернатива cron)
.mount    — точка монтирования
.path     — отслеживание файлов/директорий
.slice    — группа процессов (управление ресурсами)

# Расположение юнитов:
/lib/systemd/system/     — системные (из пакетов)
/etc/systemd/system/     — пользовательские (переопределение)
/run/systemd/system/     — временные (runtime)`)

	// ─── 35. Управление сервисами ─────────────────────────────────
	utils.Section("35. Системный менеджер systemd: управление сервисами")

	utils.Println(utils.ColorBold + "systemctl — основные команды:" + utils.ColorReset)
	utils.Command("systemctl status nginx", "статус сервиса")
	utils.Command("systemctl start nginx", "запустить")
	utils.Command("systemctl stop nginx", "остановить")
	utils.Command("systemctl restart nginx", "перезапустить")
	utils.Command("systemctl reload nginx", "перечитать конфигурацию")
	utils.Command("systemctl enable nginx", "включить автозапуск")
	utils.Command("systemctl disable nginx", "выключить автозапуск")
	utils.Command("systemctl enable --now nginx", "включить и сразу запустить")
	utils.Command("systemctl disable --now nginx", "выключить и остановить")
	utils.Command("systemctl is-active nginx", "активен? (active/inactive)")
	utils.Command("systemctl is-enabled nginx", "в автозапуске? (enabled/disabled)")
	utils.Command("systemctl is-failed nginx", "завершился с ошибкой?")
	fmt.Println()
	utils.Command("systemctl list-units", "список всех активных юнитов")
	utils.Command("systemctl list-units --type=service", "только сервисы")
	utils.Command("systemctl list-units --failed", "упавшие юниты")
	utils.Command("systemctl list-unit-files", "все юниты и их состояние")
	utils.Command("systemctl daemon-reload", "перечитать файлы юнитов (после изменений)")
	fmt.Println()
	utils.Println(utils.ColorBold + "Таргеты (targets) — уровни запуска:" + utils.ColorReset)
	utils.Code(`poweroff.target    — выключение (runlevel 0)
rescue.target      — однопользовательский (runlevel 1)
multi-user.target  — многопользовательский без GUI (runlevel 3)
graphical.target   — с GUI (runlevel 5)
reboot.target      — перезагрузка (runlevel 6)

# Текущий таргет:
systemctl get-default

# Изменить таргет по умолчанию:
systemctl set-default multi-user.target

# Переключиться немедленно:
systemctl isolate multi-user.target

# Выключение и перезагрузка:
systemctl poweroff
systemctl reboot
systemctl suspend
systemctl hibernate`)

	utils.Println(utils.ColorBold + "journalctl — просмотр логов systemd:" + utils.ColorReset)
	utils.Command("journalctl", "все логи")
	utils.Command("journalctl -u nginx", "логи конкретного сервиса")
	utils.Command("journalctl -f", "следить в реальном времени")
	utils.Command("journalctl -f -u nginx", "следить за nginx")
	utils.Command("journalctl -n 50", "последние 50 строк")
	utils.Command("journalctl --since '2024-01-15 10:00'", "с определённого времени")
	utils.Command("journalctl --since '1 hour ago'", "за последний час")
	utils.Command("journalctl -p err", "только ошибки (emerg alert crit err warning notice info debug)")
	utils.Command("journalctl -b", "с момента последней загрузки")
	utils.Command("journalctl -b -1", "предыдущая загрузка")
	utils.Command("journalctl --disk-usage", "объём логов на диске")
	utils.Command("journalctl --vacuum-size=100M", "оставить только 100МБ логов")

	// ─── 41. Systemd юниты ────────────────────────────────────────
	utils.Section("41. Создание systemd юнитов")

	utils.Println(utils.ColorBold + "Структура .service файла:" + utils.ColorReset)
	utils.Code(`# /etc/systemd/system/myapp.service
[Unit]
Description=My Application
Documentation=https://example.com
After=network.target         # запустить после сети
Requires=postgresql.service  # обязательная зависимость
Wants=redis.service          # желательная зависимость

[Service]
Type=simple           # forking, oneshot, notify, idle
User=myapp            # от какого пользователя
Group=myapp
WorkingDirectory=/opt/myapp
ExecStart=/opt/myapp/bin/myapp --config /etc/myapp.conf
ExecReload=/bin/kill -HUP $MAINPID
Restart=on-failure    # always, on-failure, on-abnormal
RestartSec=5
StandardOutput=journal
StandardError=journal
Environment=NODE_ENV=production
EnvironmentFile=/etc/myapp/env

# Ограничения:
MemoryMax=512M
CPUQuota=50%
LimitNOFILE=65536

[Install]
WantedBy=multi-user.target`)

	utils.Code(`# Применить новый юнит:
sudo systemctl daemon-reload
sudo systemctl enable --now myapp

# Переопределить параметры (без редактирования оригинала):
sudo systemctl edit nginx        # создаёт /etc/systemd/system/nginx.service.d/override.conf`)

	utils.Println(utils.ColorBold + "Timer юнит (альтернатива cron):" + utils.ColorReset)
	utils.Code(`# /etc/systemd/system/backup.timer
[Unit]
Description=Ежедневный бэкап

[Timer]
OnCalendar=*-*-* 02:00:00    # каждый день в 02:00
OnCalendar=Mon *-*-* 03:00   # каждый понедельник в 03:00
OnBootSec=15min               # через 15 мин после загрузки
OnUnitActiveSec=1h            # каждый час после последнего запуска
Persistent=true               # запустить если пропустили время

[Install]
WantedBy=timers.target

# /etc/systemd/system/backup.service
[Unit]
Description=Скрипт бэкапа

[Service]
Type=oneshot
ExecStart=/usr/local/bin/backup.sh`)

	utils.Footer()
}
