package linuxmodules

import (
	"rubric/utils"
)

var KernelModule = Module{
	Key:         "kernel",
	Aliases:     []string{"k", "ядро"},
	Title:       "Ядро Linux",
	Description: "Тема 21: ядро, модули, параметры, uname, dmesg",
	Run:         showKernel,
}

func showKernel() {
	utils.Header("Linux — Ядро (Kernel)")

	utils.Section("21. Ядро Linux")

	utils.Println("Ядро (kernel) — центральная часть ОС. Управляет:")
	utils.Println("• процессами и планировщиком CPU")
	utils.Println("• памятью (виртуальная память, swap)")
	utils.Println("• устройствами (через драйверы)")
	utils.Println("• файловыми системами")
	utils.Println("• сетью")
	utils.Println("• системными вызовами (syscalls)")

	utils.Println(utils.ColorBold + "\nИнформация о ядре:" + utils.ColorReset)
	utils.Command("uname -r", "версия ядра")
	utils.Command("uname -a", "полная информация (ядро, архитектура, дата)")
	utils.Command("uname -m", "архитектура (x86_64, aarch64...)")
	utils.Command("cat /proc/version", "подробная версия (компилятор, дата)")
	utils.Command("cat /proc/sys/kernel/osrelease", "версия через /proc")
	utils.Code(`# Пример uname -a:
Linux server01 5.15.0-91-generic #101-Ubuntu SMP Tue Nov 14 13:30:08 UTC 2023
x86_64 x86_64 x86_64 GNU/Linux
│       │       │       └ платформа
│       │       └── архитектура процессора
│       └── имя хоста
└── имя ядра

# Версия ядра: 5.15.0-91-generic
# 5.15 — основная версия
# 0    — патч-уровень
# 91   — номер пакета дистрибутива`)

	utils.Println(utils.ColorBold + "dmesg — буфер сообщений ядра:" + utils.ColorReset)
	utils.Command("dmesg", "все сообщения ядра")
	utils.Command("dmesg | tail -20", "последние 20 сообщений")
	utils.Command("dmesg -T", "с человекочитаемыми временными метками")
	utils.Command("dmesg | grep -i error", "только ошибки")
	utils.Command("dmesg | grep -i usb", "сообщения о USB-устройствах")
	utils.Command("dmesg | grep -i sda", "сообщения о диске sda")
	utils.Command("dmesg -w", "следить за новыми сообщениями (как tail -f)")
	utils.Command("dmesg -l err,crit", "только критические ошибки")

	utils.Println(utils.ColorBold + "\nМодули ядра:" + utils.ColorReset)
	utils.Println("Модуль — расширение ядра, загружаемое динамически (драйверы, ФС...).")
	utils.Code(`# Управление модулями:
lsmod                    # список загруженных модулей
lsmod | grep ext4        # есть ли модуль ext4?
modinfo ext4             # информация о модуле
modprobe ext4            # загрузить модуль (с зависимостями)
modprobe -r ext4         # выгрузить модуль
insmod /path/to/mod.ko   # загрузить .ko файл напрямую
rmmod ext4               # выгрузить модуль

# Автоматическая загрузка при старте:
# /etc/modules (Debian/Ubuntu)
# /etc/modules-load.d/*.conf
echo "br_netfilter" > /etc/modules-load.d/k8s.conf

# Параметры модулей:
# /etc/modprobe.d/*.conf
echo "options kvm_intel nested=1" > /etc/modprobe.d/kvm.conf`)

	utils.Println(utils.ColorBold + "Параметры ядра (sysctl):" + utils.ColorReset)
	utils.Code(`# Просмотр параметров:
sysctl -a                          # все параметры
sysctl net.ipv4.ip_forward         # конкретный параметр
cat /proc/sys/net/ipv4/ip_forward  # то же через /proc/sys

# Изменить параметр (временно):
sysctl -w net.ipv4.ip_forward=1

# Постоянно — в /etc/sysctl.conf или /etc/sysctl.d/:
echo "net.ipv4.ip_forward = 1" >> /etc/sysctl.d/99-custom.conf
sysctl -p /etc/sysctl.d/99-custom.conf  # применить

# Полезные параметры:
net.ipv4.ip_forward = 1         # маршрутизация (для Docker/Kubernetes)
net.ipv4.tcp_syncookies = 1     # защита от SYN flood
vm.swappiness = 10              # предпочитать RAM над swap
fs.file-max = 2097152           # максимум открытых файлов
kernel.dmesg_restrict = 0       # dmesg без root`)

	utils.Println(utils.ColorBold + "Аппаратная информация:" + utils.ColorReset)
	utils.Command("lscpu", "информация о процессоре")
	utils.Command("lsmem", "информация о памяти")
	utils.Command("lspci", "устройства на шине PCI")
	utils.Command("lspci -v", "подробно")
	utils.Command("lsusb", "USB-устройства")
	utils.Command("lsblk", "блочные устройства (диски)")
	utils.Command("lshw", "полная информация об оборудовании (нужен root)")
	utils.Command("dmidecode", "данные BIOS/UEFI (тип памяти, серийный номер...)")
	utils.Command("inxi -Fz", "обзор системы (нужно установить)")

	utils.Footer()
}
