package linuxmodules

import (
	"fmt"
	"rubric/utils"
)

var UsersModule = Module{
	Key:         "users",
	Aliases:     []string{"u", "perms", "sudo", "права"},
	Title:       "Пользователи, права и sudo",
	Description: "Темы 17–20: su, sudo, пользователи, группы, права на файлы",
	Run:         showUsers,
}

func showUsers() {
	utils.Header("Linux — Пользователи, права и sudo")

	// ─── 19. Пользователи и группы ───────────────────────────────
	utils.Section("19. Пользователи и группы")

	utils.Println("В Linux каждый файл принадлежит пользователю и группе.")
	utils.Println("Каждый процесс запускается от имени определённого пользователя.")
	fmt.Println()
	utils.Println(utils.ColorBold + "Основные файлы пользователей:" + utils.ColorReset)
	utils.Code(`/etc/passwd  — список пользователей
/etc/shadow  — хэши паролей (только root)
/etc/group   — группы

# Формат /etc/passwd:
# имя:пароль:UID:GID:комментарий:home:shell
alice:x:1000:1000:Alice Smith:/home/alice:/bin/bash
root:x:0:0:root:/root:/bin/bash
# x — пароль в /etc/shadow
# UID 0 — root (суперпользователь)
# UID 1-999 — системные пользователи
# UID 1000+ — обычные пользователи

# Формат /etc/group:
# имя:пароль:GID:члены
sudo:x:27:alice,bob
docker:x:999:alice`)

	utils.Println(utils.ColorBold + "Информация о пользователях:" + utils.ColorReset)
	utils.Command("id", "UID, GID и группы текущего пользователя")
	utils.Command("id alice", "информация о пользователе alice")
	utils.Command("whoami", "имя текущего пользователя")
	utils.Command("groups", "группы текущего пользователя")
	utils.Command("getent passwd alice", "запись alice из /etc/passwd")
	utils.Command("getent group docker", "участники группы docker")
	fmt.Println()
	utils.Println(utils.ColorBold + "Управление пользователями (root):" + utils.ColorReset)
	utils.Command("useradd alice", "создать пользователя")
	utils.Command("useradd -m -s /bin/bash -G sudo alice", "с домашней директорией, оболочкой и группой")
	utils.Command("passwd alice", "установить пароль")
	utils.Command("usermod -aG docker alice", "добавить alice в группу docker")
	utils.Command("usermod -s /bin/zsh alice", "изменить оболочку")
	utils.Command("usermod -L alice", "заблокировать учётную запись")
	utils.Command("usermod -U alice", "разблокировать")
	utils.Command("userdel alice", "удалить пользователя")
	utils.Command("userdel -r alice", "удалить с домашней директорией")
	fmt.Println()
	utils.Println(utils.ColorBold + "Управление группами:" + utils.ColorReset)
	utils.Command("groupadd developers", "создать группу")
	utils.Command("groupdel developers", "удалить группу")
	utils.Command("gpasswd -a alice developers", "добавить alice в группу")
	utils.Command("gpasswd -d alice developers", "удалить alice из группы")
	fmt.Println()
	utils.Note("После добавления в группу пользователь должен перелогиниться. Или: newgrp groupname")

	// ─── 20. Права на файлы ───────────────────────────────────────
	utils.Section("20. Права на файлы")

	utils.Println(utils.ColorBold + "Структура прав доступа:" + utils.ColorReset)
	utils.Code(`ls -l file.txt
-rw-r--r-- 1 alice users 1024 Jan 15 10:00 file.txt
│└──────────┘
│ 9 бит прав
└ тип файла (- файл, d директория, l ссылка...)

Права разделены на 3 группы по 3 бита:
rwx rwx rwx
│   │   └── other  (остальные пользователи)
│   └─────── group  (группа владельца)
└─────────── owner  (владелец)

r — read    (чтение):       4
w — write   (запись):       2
x — execute (выполнение):   1
- — нет права:              0

Пример: rw-r--r--
  owner: rw-  = 6 (4+2)   — чтение и запись
  group: r--  = 4          — только чтение
  other: r--  = 4          — только чтение
  Численно: 644`)

	utils.Println(utils.ColorBold + "chmod — изменить права:" + utils.ColorReset)
	utils.Code(`# Числовой (восьмеричный) способ:
chmod 644 file.txt     # rw-r--r--
chmod 755 script.sh    # rwxr-xr-x
chmod 600 private.key  # rw-------
chmod 777 dir/         # rwxrwxrwx (небезопасно!)
chmod 750 script.sh    # rwxr-x---

# Символьный способ:
chmod u+x script.sh    # добавить execute владельцу
chmod g-w file.txt     # убрать write у группы
chmod o-r secret.txt   # убрать чтение у остальных
chmod a+r public.txt   # добавить чтение всем (a = all)
chmod u+x,g-w file     # несколько изменений
chmod go=r file.txt    # установить группе и остальным только r

# Рекурсивно:
chmod -R 755 /var/www/html/`)

	utils.Println(utils.ColorBold + "Типичные значения прав:" + utils.ColorReset)
	utils.Code(`644  rw-r--r--  обычный файл (конфиги, тексты)
755  rwxr-xr-x  исполняемый файл, директория
700  rwx------  личный скрипт/директория
600  rw-------  приватный ключ, .env файл
640  rw-r-----  конфиг с секретами (owner + group)
664  rw-rw-r--  файл для работы в группе
1777 rwxrwxrwt  /tmp (sticky bit)`)

	utils.Println(utils.ColorBold + "chown — изменить владельца:" + utils.ColorReset)
	utils.Command("chown alice file.txt", "изменить владельца")
	utils.Command("chown alice:users file.txt", "изменить владельца и группу")
	utils.Command("chown :users file.txt", "изменить только группу")
	utils.Command("chown -R alice:alice /home/alice/", "рекурсивно")
	utils.Command("chgrp users file.txt", "изменить только группу")
	fmt.Println()
	utils.Println(utils.ColorBold + "Специальные биты:" + utils.ColorReset)
	utils.Code(`SUID (Set User ID) — 4000:
  Файл запускается с правами владельца файла, а не запускающего.
  chmod u+s /usr/bin/passwd    # или chmod 4755
  ls -la: -rwsr-xr-x (s вместо x у владельца)
  Пример: passwd изменяет /etc/shadow (root-файл)

SGID (Set Group ID) — 2000:
  Файл: запускается от имени группы файла.
  Директория: новые файлы наследуют группу директории.
  chmod g+s /shared/            # или chmod 2755
  ls -la: drwxrwsr-x

Sticky Bit — 1000:
  Директория: файл может удалить только его владелец.
  chmod +t /tmp/                # или chmod 1777
  ls -la: drwxrwxrwt
  Применение: /tmp, /var/tmp`)

	utils.Println(utils.ColorBold + "umask — маска прав по умолчанию:" + utils.ColorReset)
	utils.Code(`umask определяет права, которые НЕ назначаются новым файлам.

umask           # показать текущую маску (обычно 0022)
umask 0022      # установить маску

# Как работает:
# Файлы создаются с 666, директории с 777.
# Umask 022 вычитается:
#   666 - 022 = 644  (файлы: rw-r--r--)
#   777 - 022 = 755  (директории: rwxr-xr-x)
# Umask 077:
#   666 - 077 = 600  (файлы: rw-------)
#   777 - 077 = 700  (директории: rwx------)

# Установить постоянно в ~/.bashrc:
umask 0027`)

	// ─── 17–18. su и sudo ─────────────────────────────────────────
	utils.Section("17–18. su, sudo и visudo")

	utils.Println(utils.ColorBold + "su — Switch User:" + utils.ColorReset)
	utils.Command("su -", "переключиться в root (login shell, нужен пароль root)")
	utils.Command("su", "переключиться в root (без login shell)")
	utils.Command("su - alice", "переключиться в alice")
	utils.Command("su -c 'команда' alice", "выполнить команду от имени alice")
	fmt.Println()
	utils.Code(`Разница su vs su -:
su      — только смена UID, переменные окружения остаются
su -    — полноценный вход, загружается окружение пользователя
          (PATH, HOME и т.д.)

Выйти из su: exit или Ctrl+D`)

	utils.Println(utils.ColorBold + "sudo — выполнить как другой пользователь:" + utils.ColorReset)
	utils.Command("sudo command", "выполнить команду как root")
	utils.Command("sudo -u alice command", "выполнить от имени alice")
	utils.Command("sudo -i", "интерактивная сессия root (= su -)")
	utils.Command("sudo -s", "оболочка root с текущим окружением")
	utils.Command("sudo -l", "показать разрешённые команды для текущего пользователя")
	utils.Command("sudo -l -U alice", "разрешённые команды для alice")
	utils.Command("sudo !!", "повторить последнюю команду с sudo")
	fmt.Println()
	utils.Code(`sudo кэширует аутентификацию на 15 минут (по умолчанию).
sudo -k   — сбросить кэш (следующая команда потребует пароль)`)

	utils.Println(utils.ColorBold + "visudo — редактирование /etc/sudoers:" + utils.ColorReset)
	utils.Code(`# НИКОГДА не редактируйте /etc/sudoers напрямую!
# visudo проверяет синтаксис перед сохранением.

sudo visudo

# Формат правил:
# WHO  WHERE=(AS_WHOM) WHAT

# Примеры /etc/sudoers:
root    ALL=(ALL:ALL) ALL         # root имеет все права
%sudo   ALL=(ALL:ALL) ALL         # группа sudo — все права
%wheel  ALL=(ALL:ALL) ALL         # RHEL: группа wheel

alice   ALL=(ALL) ALL             # alice — все команды
alice   ALL=(ALL) NOPASSWD:ALL    # без пароля (небезопасно!)
bob     ALL=(root) /usr/bin/apt   # только apt от root
netadmin ALL=(root) /usr/bin/nmtui # только nmtui
helpdesk ALL=(root) /usr/bin/passwd, !/usr/bin/passwd root  # пароли кроме root

# Файлы из /etc/sudoers.d/ включаются автоматически.
# Лучше создавать файл там, а не редактировать sudoers:
sudo visudo -f /etc/sudoers.d/alice`)

	utils.Footer()
}
