package linuxmodules

import (
	"fmt"
	"rubric/utils"
)

var NetfsModule = Module{
	Key:         "netfs",
	Aliases:     []string{"nfs", "smb", "samba", "autofs", "сетевые-фс"},
	Title:       "Сетевые файловые системы",
	Description: "Темы 55–59: IPv6, передача файлов, NFS, SMB/Samba, autofs",
	Run:         showNetfs,
}

func showNetfs() {
	utils.Header("Linux — Сетевые файловые системы")

	// ─── 55. IPv6 ─────────────────────────────────────────────────
	utils.Section("55. Работа с IPv6")

	utils.Println("IPv6 — протокол интернета следующего поколения (128-битные адреса).")
	fmt.Println()
	utils.Println(utils.ColorBold + "Формат IPv6 адресов:" + utils.ColorReset)
	utils.Code(`Формат: 8 групп по 4 hex-цифры, разделённых :
2001:0db8:85a3:0000:0000:8a2e:0370:7334

Сокращения:
- Ведущие нули в группе можно опустить: 0db8 → db8
- Одну последовательность групп из нулей → ::
2001:db8::1         (полный: 2001:0db8:0000:0000:0000:0000:0000:0001)
::1                 — loopback (аналог 127.0.0.1)
fe80::/10           — link-local (автоконфигурация в подсети)
fd00::/8            — уникальные локальные (аналог 192.168.x.x)
2000::/3            — глобальные unicast (публичные)

Длина префикса: 2001:db8::/32  (аналог маски подсети)`)

	utils.Println(utils.ColorBold + "Настройка IPv6 через nmcli:" + utils.ColorReset)
	utils.Code(`# Статический IPv6:
nmcli con mod eth0 ipv6.addresses "2001:db8::10/64"
nmcli con mod eth0 ipv6.gateway "2001:db8::1"
nmcli con mod eth0 ipv6.method manual
nmcli con up eth0

# SLAAC (автоконфигурация):
nmcli con mod eth0 ipv6.method auto

# DHCPv6:
nmcli con mod eth0 ipv6.method dhcp

# Отключить IPv6 для интерфейса:
nmcli con mod eth0 ipv6.method disabled`)

	utils.Println(utils.ColorBold + "IPv6 команды:" + utils.ColorReset)
	utils.Command("ip -6 addr", "IPv6 адреса интерфейсов")
	utils.Command("ip -6 route", "IPv6 таблица маршрутов")
	utils.Command("ping6 ::1", "ping loopback IPv6")
	utils.Command("ping6 fe80::1%eth0", "ping link-local с указанием интерфейса")
	utils.Command("traceroute6 2001:4860:4860::8888", "traceroute IPv6")
	utils.Command("ss -6 -tuln", "IPv6 порты")
	utils.Command("dig AAAA google.com", "DNS AAAA запись (IPv6)")

	// ─── 56. Передача файлов по сети ─────────────────────────────
	utils.Section("56. Передача файлов по сети")

	utils.Println(utils.ColorBold + "SCP — копирование через SSH:" + utils.ColorReset)
	utils.Code(`# Скопировать локальный файл на сервер:
scp file.txt user@server:/path/to/dest/

# Скопировать с сервера на локальную машину:
scp user@server:/path/file.txt /local/path/

# Директорию рекурсивно:
scp -r mydir/ user@server:/tmp/

# Нестандартный порт:
scp -P 2222 file.txt user@server:/tmp/

# С указанием ключа:
scp -i ~/.ssh/mykey file.txt user@server:/tmp/

# Между двумя серверами:
scp user1@server1:/path/file.txt user2@server2:/path/`)

	utils.Println(utils.ColorBold + "SFTP — интерактивная передача файлов:" + utils.ColorReset)
	utils.Code(`# Подключиться:
sftp user@server
sftp -P 2222 user@server

# Команды в интерактивном режиме:
ls                  — список файлов на сервере
lls                 — список файлов локально
pwd                 — директория на сервере
lpwd                — локальная директория
cd /remote/path     — перейти на сервере
lcd /local/path     — перейти локально
get file.txt        — скачать файл
get -r dir/         — скачать директорию
put file.txt        — загрузить файл
put -r dir/         — загрузить директорию
rm file.txt         — удалить на сервере
mkdir newdir        — создать директорию на сервере
exit / quit         — выйти`)

	utils.Println(utils.ColorBold + "rsync — эффективная синхронизация:" + utils.ColorReset)
	utils.Code(`# rsync передаёт только изменения — быстрее scp для больших объёмов.

# Синхронизировать локально:
rsync -av /source/ /dest/

# Синхронизировать на удалённый сервер:
rsync -avz /local/data/ user@server:/remote/data/

# С сервера локально:
rsync -avz user@server:/remote/data/ /local/data/

# Ключи:
# -a  — архивный режим (сохраняет права, время, симлинки)
# -v  — verbose
# -z  — сжатие при передаче
# -P  — прогресс + продолжение прерванной передачи
# --delete  — удалять файлы которых нет в источнике
# --exclude='*.log'  — исключить паттерн
# -n / --dry-run  — симуляция (что будет скопировано)
# -e "ssh -p 2222"  — нестандартный порт SSH

# Зеркалирование с исключениями:
rsync -avz --delete \
    --exclude='.git/' \
    --exclude='node_modules/' \
    /project/ user@server:/var/www/project/`)

	// ─── 57. NFS ──────────────────────────────────────────────────
	utils.Section("57. Сетевые файловые системы — NFS")

	utils.Println("NFS (Network File System) — монтирование директорий с удалённых серверов.")
	utils.Println("Прозрачно для приложений: работает как обычная локальная ФС.")
	fmt.Println()
	utils.Println(utils.ColorBold + "Сервер NFS — настройка экспорта:" + utils.ColorReset)
	utils.Code(`# Установка:
dnf install nfs-utils      # RHEL/Fedora
apt install nfs-kernel-server  # Debian/Ubuntu

# Включить и запустить:
systemctl enable --now nfs-server  # RHEL
systemctl enable --now nfs-kernel-server  # Ubuntu

# Настройка экспортов /etc/exports:
# директория  клиент(опции)
/shared           192.168.1.0/24(rw,sync,no_root_squash)
/data             *(ro,sync)                    # всем только чтение
/home/alice       server2(rw,sync,no_subtree_check)

# Опции:
# rw           — чтение и запись
# ro           — только чтение
# sync         — синхронная запись (безопасно)
# async        — асинхронная (быстрее, риск потери)
# no_root_squash — root клиента = root сервера
# root_squash  — root клиента → nobody (безопаснее, по умолчанию)
# no_subtree_check — не проверять поддерево (производительность)

# Применить изменения:
exportfs -r          # перечитать /etc/exports
exportfs -v          # показать активные экспорты
exportfs -a          # экспортировать всё из /etc/exports`)

	utils.Println(utils.ColorBold + "Firewall для NFS:" + utils.ColorReset)
	utils.Code(`firewall-cmd --permanent --add-service=nfs
firewall-cmd --permanent --add-service=rpc-bind
firewall-cmd --permanent --add-service=mountd
firewall-cmd --reload`)

	utils.Println(utils.ColorBold + "Клиент NFS — монтирование:" + utils.ColorReset)
	utils.Code(`# Установка клиента:
dnf install nfs-utils
apt install nfs-common

# Посмотреть экспорты сервера:
showmount -e 192.168.1.10

# Смонтировать:
mount -t nfs 192.168.1.10:/shared /mnt/shared
mount -t nfs4 192.168.1.10:/data /mnt/data   # NFSv4

# Параметры монтирования:
mount -t nfs -o rw,sync,hard,intr 192.168.1.10:/shared /mnt

# В /etc/fstab (постоянно):
192.168.1.10:/shared  /mnt/shared  nfs  defaults,_netdev  0 0
# _netdev — монтировать только после настройки сети

# Размонтировать:
umount /mnt/shared`)

	// ─── 58. SMB/Samba ────────────────────────────────────────────
	utils.Section("58. Сетевые файловые системы — SMB/Samba")

	utils.Println("SMB (Server Message Block) / CIFS — протокол файлового обмена Windows.")
	utils.Println("Samba — реализация SMB на Linux. Позволяет обмениваться файлами с Windows.")
	fmt.Println()
	utils.Println(utils.ColorBold + "Сервер Samba — установка и настройка:" + utils.ColorReset)
	utils.Code(`# Установка:
dnf install samba samba-client   # RHEL
apt install samba                # Ubuntu

# Включить и запустить:
systemctl enable --now smb nmb   # RHEL
systemctl enable --now smbd nmbd # Ubuntu`)

	utils.Println(utils.ColorBold + "Конфигурация /etc/samba/smb.conf:" + utils.ColorReset)
	utils.Code(`[global]
    workgroup = WORKGROUP           # рабочая группа Windows
    server string = Samba Server
    security = user                 # аутентификация по пользователю
    passdb backend = tdbsam         # база паролей

# Публичная шара (без пароля):
[public]
    path = /srv/samba/public
    browseable = yes
    writable = yes
    guest ok = yes
    create mask = 0664
    directory mask = 0775

# Приватная шара (с паролем):
[private]
    path = /srv/samba/private
    valid users = alice bob
    writable = yes
    browseable = no
    create mask = 0660`)

	utils.Println(utils.ColorBold + "Управление пользователями Samba:" + utils.ColorReset)
	utils.Code(`# Пользователь Samba должен существовать в Linux:
useradd -s /sbin/nologin alice

# Добавить пользователя в Samba (отдельный пароль!):
smbpasswd -a alice
smbpasswd -e alice      # включить
smbpasswd -d alice      # отключить
smbpasswd -x alice      # удалить

# Список пользователей Samba:
pdbedit -L`)

	utils.Println(utils.ColorBold + "SELinux + Samba:" + utils.ColorReset)
	utils.Code(`# Разрешить Samba доступ к домашним директориям:
setsebool -P samba_enable_home_dirs on

# Разрешить Samba читать/писать общие директории:
chcon -t samba_share_t /srv/samba/public
semanage fcontext -a -t samba_share_t '/srv/samba(/.*)?'
restorecon -Rv /srv/samba/`)

	utils.Println(utils.ColorBold + "Firewall для Samba:" + utils.ColorReset)
	utils.Code(`firewall-cmd --permanent --add-service=samba
firewall-cmd --reload`)

	utils.Println(utils.ColorBold + "Клиент SMB — монтирование Windows-шары:" + utils.ColorReset)
	utils.Code(`# Установка:
dnf install cifs-utils samba-client
apt install cifs-utils smbclient

# Просмотр шар на сервере:
smbclient -L //192.168.1.20 -U alice

# Интерактивный клиент:
smbclient //192.168.1.20/shared -U alice

# Монтирование:
mount -t cifs //192.168.1.20/shared /mnt/windows \
    -o username=alice,password=secret

# С файлом учётных данных (безопаснее):
cat > /etc/samba/creds << 'EOF'
username=alice
password=secret
domain=WORKGROUP
EOF
chmod 600 /etc/samba/creds

mount -t cifs //192.168.1.20/shared /mnt/windows \
    -o credentials=/etc/samba/creds

# В /etc/fstab:
//server/shared  /mnt/windows  cifs  credentials=/etc/samba/creds,_netdev  0 0`)

	// ─── 59. Autofs ───────────────────────────────────────────────
	utils.Section("59. Автоматическое монтирование — Autofs")

	utils.Println("Autofs — демон автоматического монтирования сетевых ФС по запросу.")
	utils.Println("Монтирует при обращении к директории, размонтирует при простое.")
	fmt.Println()
	utils.Println(utils.ColorBold + "Установка и запуск:" + utils.ColorReset)
	utils.Code(`dnf install autofs      # RHEL
apt install autofs      # Ubuntu

systemctl enable --now autofs`)

	utils.Println(utils.ColorBold + "Конфигурация autofs:" + utils.ColorReset)
	utils.Code(`# Главный файл /etc/auto.master:
# точка_монтирования  файл_карты  [опции]
/mnt/nfs    /etc/auto.nfs    --timeout=60
/home       /etc/auto.home   --timeout=300
/-          /etc/auto.direct

# /etc/auto.nfs — монтирование NFS:
# ключ   опции          сервер:путь
shared  -rw,sync        192.168.1.10:/shared
data    -ro             192.168.1.10:/data
# Обращение: ls /mnt/nfs/shared → автоматически монтируется

# /etc/auto.home — домашние директории через NFS:
*  -rw,sync  192.168.1.10:/home/&
# & → подставляется ключ (* = любой пользователь)
# /home/alice → монтируется 192.168.1.10:/home/alice

# /etc/auto.direct — прямые точки монтирования:
/srv/data  -rw,sync  192.168.1.10:/data

# Применить изменения:
systemctl reload autofs
# или:
automount -v`)

	utils.Println(utils.ColorBold + "Использование с FreeIPA/LDAP:" + utils.ColorReset)
	utils.Code(`# FreeIPA хранит карты autofs в LDAP.
# После настройки sssd + ipa-client autofs
# получает карты автоматически.

# Подключить autofs к SSSD:
# В /etc/sssd/sssd.conf:
[domain/ipa.example.com]
autofs_provider = ipa

# Перезапустить:
systemctl restart sssd autofs`)

	utils.Note("Autofs удобен для сотен пользователей: их домашние директории монтируются автоматически при входе.")
	utils.Note("--timeout=60 означает размонтировать после 60 секунд бездействия.")

	utils.Footer()
}
