package linuxmodules

import (
	"fmt"
	"rubric/utils"
)

var ToolsModule = Module{
	Key:         "tools",
	Aliases:     []string{"t", "cockpit", "regex", "awk", "sed", "инструменты"},
	Title:       "Веб-интерфейс и текстовые инструменты",
	Description: "Темы 60–61: Cockpit, глоббинг, регулярные выражения, grep, sed, awk",
	Run:         showTools,
}

func showTools() {
	utils.Header("Linux — Веб-интерфейс и текстовые инструменты")

	// ─── 60. Cockpit ──────────────────────────────────────────────
	utils.Section("60. Веб-интерфейс — Cockpit")

	utils.Println("Cockpit — веб-консоль для администрирования Linux через браузер.")
	utils.Println("Позволяет управлять сервисами, сетью, дисками, контейнерами и логами.")
	fmt.Println()
	utils.Println(utils.ColorBold + "Установка и запуск:" + utils.ColorReset)
	utils.Code(`# RHEL/Fedora (обычно предустановлен):
dnf install cockpit
systemctl enable --now cockpit.socket

# Ubuntu/Debian:
apt install cockpit
systemctl enable --now cockpit.socket

# Открыть порт в firewalld:
firewall-cmd --permanent --add-service=cockpit
firewall-cmd --reload

# Доступ: https://hostname:9090
# Войти с логином/паролем системного пользователя`)

	utils.Println(utils.ColorBold + "Расширения Cockpit:" + utils.ColorReset)
	utils.Code(`# Управление виртуальными машинами:
dnf install cockpit-machines

# Управление Podman-контейнерами:
dnf install cockpit-podman

# Управление хранилищем (LVM, RAID, Stratis):
dnf install cockpit-storaged

# 389 DS (LDAP):
dnf install cockpit-389-ds

# Обновления пакетов:
dnf install cockpit-packagekit

# Применить все расширения:
systemctl restart cockpit.socket`)

	utils.Println(utils.ColorBold + "Возможности Cockpit:" + utils.ColorReset)
	utils.Code(`Dashboard       — обзор системы: CPU, RAM, диски, сеть
Services        — управление systemd-сервисами
Storage         — диски, LVM, RAID, Stratis, NFS
Networking      — интерфейсы, маршруты, firewall
Accounts        — пользователи и группы
Software Updates — обновление пакетов
Terminal        — встроенный терминал в браузере
Logs            — journald логи с фильтрами
Podman          — управление контейнерами
Machines        — виртуальные машины (KVM/libvirt)`)

	utils.Note("Cockpit работает в браузере, не требует постоянного подключения: сессия = одна вкладка.")
	utils.Note("Порт 9090. Сертификат самоподписанный — нужно добавить исключение в браузере или подключить Let's Encrypt.")

	// ─── 61. Глоббинг и регулярные выражения ─────────────────────
	utils.Section("61. Глоббинг и регулярные выражения")

	utils.Println(utils.ColorBold + "Глоббинг (Globbing) — шаблоны оболочки:" + utils.ColorReset)
	utils.Code(`*        — любое количество любых символов (кроме /)
?        — ровно один любой символ
[abc]    — один символ из набора
[a-z]    — один символ из диапазона
[!abc]   — один символ НЕ из набора
{a,b,c}  — одно из перечисленных

# Примеры:
ls *.log                   # все файлы .log
ls file?.txt               # file1.txt, fileA.txt...
ls [0-9]*.conf             # начинающиеся с цифры
ls /etc/{nginx,apache}*    # /etc/nginx* или /etc/apache*
rm backup_{2023,2024}*.tar # удалить бэкапы 2023 и 2024
cp /etc/*.{conf,cfg} /tmp/ # все .conf и .cfg

# Расширенный глоббинг (shopt -s extglob):
?(pattern)  — 0 или 1 вхождение
*(pattern)  — 0 или более
+(pattern)  — 1 или более
@(pattern)  — ровно 1
!(pattern)  — всё кроме`)

	utils.Println(utils.ColorBold + "Регулярные выражения — базовые (BRE):" + utils.ColorReset)
	utils.Code(`.        — любой символ
*        — 0 или более предыдущего
^        — начало строки
$        — конец строки
[abc]    — один символ из набора
[^abc]   — один символ НЕ из набора
\(abc\)  — группа
\{n,m\}  — от n до m повторений

# Примеры:
grep '^root' /etc/passwd     # строки начинающиеся с root
grep 'bash$' /etc/passwd     # строки оканчивающиеся на bash
grep '^$' file.txt           # пустые строки
grep '[0-9]\{3\}' file.txt   # три цифры подряд`)

	utils.Println(utils.ColorBold + "Регулярные выражения — расширенные (ERE):" + utils.ColorReset)
	utils.Code(`+        — 1 или более предыдущего
?        — 0 или 1 предыдущего
|        — ИЛИ
(abc)    — группа (без \)
{n,m}    — от n до m повторений (без \)

# Использование ERE: grep -E, egrep, sed -E, awk

grep -E 'cat|dog' file.txt        # cat или dog
grep -E '^[0-9]+\.' file.txt      # строки начинающиеся с числа.
grep -E '([0-9]{1,3}\.){3}[0-9]{1,3}' file.txt  # IPv4-адрес
grep -E 'error|warning|critical' /var/log/syslog

# Полезные классы символов:
[[:alpha:]]   — буквы (a-z, A-Z)
[[:digit:]]   — цифры (0-9)
[[:alnum:]]   — буквы и цифры
[[:space:]]   — пробельные символы
[[:upper:]]   — заглавные буквы
[[:lower:]]   — строчные буквы
[[:punct:]]   — знаки препинания`)

	utils.Println(utils.ColorBold + "grep — поиск по шаблону:" + utils.ColorReset)
	utils.Command("grep 'pattern' file", "базовый поиск")
	utils.Command("grep -i 'pattern' file", "без учёта регистра")
	utils.Command("grep -v 'pattern' file", "строки НЕ совпадающие")
	utils.Command("grep -n 'pattern' file", "с номерами строк")
	utils.Command("grep -c 'pattern' file", "количество совпадений")
	utils.Command("grep -l 'pattern' *.conf", "только имена файлов")
	utils.Command("grep -r 'pattern' /etc/", "рекурсивно в директории")
	utils.Command("grep -A 3 'pattern' file", "3 строки ПОСЛЕ совпадения")
	utils.Command("grep -B 2 'pattern' file", "2 строки ДО совпадения")
	utils.Command("grep -C 2 'pattern' file", "2 строки до и после")
	utils.Command("grep -E 'pat1|pat2' file", "расширенные регулярки")
	utils.Command("grep -P '\\d+' file", "Perl-совместимые regex")
	utils.Command("grep -o 'pattern' file", "только совпадающая часть")
	utils.Command("grep -w 'word' file", "только целые слова")
	fmt.Println()

	utils.Println(utils.ColorBold + "sed — потоковый редактор:" + utils.ColorReset)
	utils.Code(`# Синтаксис: sed 'команда' файл
# -i — изменить файл на месте
# -E — расширенные регулярки

# Замена (s — substitute):
sed 's/old/new/'       file    # первое вхождение в каждой строке
sed 's/old/new/g'      file    # все вхождения (global)
sed 's/old/new/gi'     file    # без учёта регистра
sed 's/old/new/2'      file    # второе вхождение

# Разделитель можно менять (удобно для путей):
sed 's|/old/path|/new/path|g'  file
sed 's#/etc#/conf#g'           file

# Изменить файл на месте:
sed -i 's/old/new/g' file.conf
sed -i.bak 's/old/new/g' file.conf   # сохранить бэкап .bak

# Удаление строк:
sed '/pattern/d'   file    # удалить строки с паттерном
sed '5d'           file    # удалить 5-ю строку
sed '2,10d'        file    # удалить строки 2-10
sed '/^$/d'        file    # удалить пустые строки
sed '/^#/d'        file    # удалить комментарии

# Вставка и добавление:
sed '3a новая строка'  file    # добавить после строки 3
sed '3i новая строка'  file    # вставить перед строкой 3
sed '$a последняя'     file    # добавить в конец

# Вывод конкретных строк:
sed -n '5,10p'     file    # напечатать строки 5-10
sed -n '/start/,/end/p' file  # между паттернами

# Несколько команд:
sed -e 's/foo/bar/' -e 's/baz/qux/' file
sed 's/foo/bar/; s/baz/qux/'        file

# Практические примеры:
# Удалить комментарии и пустые строки:
sed '/^#/d; /^$/d' nginx.conf

# Заменить IP во всех конфигах:
sed -i 's/192\.168\.1\.100/10\.0\.0\.1/g' /etc/nginx/*.conf

# Добавить строку после первого совпадения:
sed '/\[global\]/a     log level = 2' /etc/samba/smb.conf`)

	utils.Println(utils.ColorBold + "awk — обработка текста по полям:" + utils.ColorReset)
	utils.Code(`# awk обрабатывает текст построчно, разбивая на поля.
# По умолчанию разделитель — пробел/таб.

# Поля: $1 $2 $3 ... $NF (последнее), $0 (вся строка)
# NF — количество полей, NR — номер строки

# Вывод конкретного поля:
awk '{print $1}' file          # первое поле
awk '{print $1, $3}' file      # первое и третье
awk '{print NR, $0}' file      # с номерами строк

# Другой разделитель (-F):
awk -F: '{print $1}' /etc/passwd          # имена пользователей
awk -F: '{print $1, $6}' /etc/passwd      # имя и домашняя директория
awk -F, '{print $2}' data.csv             # второй столбец CSV

# Условия:
awk '$3 > 1000' file               # строки где 3-е поле > 1000
awk '/pattern/ {print $0}' file    # строки с паттерном
awk '$1 == "root"' /etc/passwd     # строки где $1 = "root"

# Вычисления:
awk '{sum += $1} END {print sum}' file  # сумма первого столбца
awk 'END {print NR}' file               # количество строк (= wc -l)

# BEGIN и END блоки:
awk 'BEGIN {print "Начало"} {print $1} END {print "Конец"}' file

# Переменные и форматирование:
awk -F: '{printf "%-20s %s\n", $1, $6}' /etc/passwd

# Практические примеры:
# Топ процессов по CPU:
ps aux | awk 'NR>1 {print $3, $11}' | sort -rn | head -10

# Сумма размеров файлов (ls -l):
ls -l | awk '{sum += $5} END {print sum " bytes"}'

# Уникальные IP из лога nginx:
awk '{print $1}' /var/log/nginx/access.log | sort | uniq -c | sort -rn

# Обработка CSV:
awk -F, 'NR>1 && $3 > 100 {print $1, $2}' report.csv`)

	utils.Footer()
}
