package linuxmodules

import (
	"fmt"
	"rubric/utils"
)

var StreamsModule = Module{
	Key:         "streams",
	Aliases:     []string{"st", "io", "потоки"},
	Title:       "Стандартные потоки и перенаправление",
	Description: "Тема 11: stdin, stdout, stderr, перенаправление, pipe",
	Run:         showStreams,
}

func showStreams() {
	utils.Header("Linux — Стандартные потоки и перенаправление")

	// ─── 11. Стандартные потоки ───────────────────────────────────
	utils.Section("11. Стандартные потоки (Standard Streams)")

	utils.Println("Каждый процесс в Linux имеет три стандартных потока ввода-вывода:")
	fmt.Println()
	utils.Code(`Дескриптор  Имя      Поток          По умолчанию
──────────────────────────────────────────────────────
0           stdin    ввод           клавиатура
1           stdout   вывод          терминал
2           stderr   вывод ошибок   терминал

Программа читает из stdin, пишет результат в stdout,
ошибки — в stderr.`)

	utils.Println(utils.ColorBold + "Перенаправление вывода (stdout):" + utils.ColorReset)
	utils.Code(`>   — перенаправить stdout в файл (перезаписать)
>>  — перенаправить stdout в файл (дописать в конец)

ls /etc > list.txt          # список файлов → файл
echo "строка" >> log.txt    # дописать в конец
date > /dev/null            # выбросить вывод в никуда`)

	utils.Println(utils.ColorBold + "Перенаправление ошибок (stderr):" + utils.ColorReset)
	utils.Code(`2>   — перенаправить stderr в файл
2>>  — дописать stderr в файл
2>&1 — направить stderr туда же куда stdout

ls /nonexistent 2> errors.txt        # ошибки → файл
ls /etc 1> out.txt 2> err.txt        # каждый поток отдельно
ls /etc /nonexistent > all.txt 2>&1  # всё в один файл
ls /etc /nonexistent &> all.txt      # краткая форма bash
ls /etc /nonexistent 2>/dev/null     # подавить ошибки`)

	utils.Println(utils.ColorBold + "Перенаправление ввода (stdin):" + utils.ColorReset)
	utils.Code(`<   — читать stdin из файла

sort < unsorted.txt         # отсортировать содержимое файла
wc -l < file.txt            # считать строки из файла

# Here-document — передать несколько строк:
cat << EOF
строка 1
строка 2
EOF

# Here-string — передать строку:
grep 'pattern' <<< "одна строка для поиска"`)

	utils.Println(utils.ColorBold + "Конвейер (pipe) |:" + utils.ColorReset)
	utils.Println("Pipe передаёт stdout одной команды в stdin следующей.")
	utils.Code(`ls -la | grep '.conf'          # только .conf файлы
cat /etc/passwd | sort         # отсортировать passwd
ps aux | grep nginx            # найти процессы nginx
cat file.txt | wc -l           # посчитать строки
ls /etc | head -10             # первые 10 строк
history | tail -20 | grep git  # цепочка из трёх команд`)

	utils.Println(utils.ColorBold + "tee — записать и передать дальше:" + utils.ColorReset)
	utils.Code(`# tee читает stdin, пишет в файл И в stdout:
ls -la | tee listing.txt | grep '.conf'

# -a — дописать в файл (append):
echo "строка" | tee -a log.txt`)

	utils.Println(utils.ColorBold + "xargs — передать строки как аргументы:" + utils.ColorReset)
	utils.Code(`# find возвращает список файлов, xargs передаёт их rm:
find /tmp -name '*.tmp' | xargs rm -f

# -I{} — подстановка каждой строки в {}: 
cat hosts.txt | xargs -I{} ping -c1 {}

# -P4 — параллельно (4 процесса):
cat urls.txt | xargs -P4 -I{} curl -O {}`)

	utils.Println(utils.ColorBold + "/dev/null и /dev/zero:" + utils.ColorReset)
	utils.Code(`/dev/null   — "чёрная дыра": запись выбрасывается, чтение → EOF
/dev/zero   — бесконечный источник нулевых байт
/dev/random — случайные байты (медленно, использует энтропию)
/dev/urandom — псевдослучайные байты (быстро)

# Типичные применения:
command > /dev/null 2>&1       # подавить весь вывод
dd if=/dev/zero of=file bs=1M count=100  # создать 100МБ файл
cat /dev/urandom | head -c 16 | base64   # случайный токен`)

	utils.Println(utils.ColorBold + "Подстановка команд (command substitution):" + utils.ColorReset)
	utils.Code(`# Результат команды используется как аргумент:
echo "Сегодня: $(date)"
ls -la $(which python3)
mkdir backup_$(date +%Y%m%d)

# Старый стиль (обратные кавычки):
echo "Версия: $(uname -r)"   # backtick-форма устарела, используйте $()`)

	utils.Println(utils.ColorBold + "Полезные фильтры для pipe:" + utils.ColorReset)
	utils.Command("grep", "фильтр строк по паттерну")
	utils.Command("sed 's/old/new/g'", "замена текста в потоке")
	utils.Command("awk '{print $1}'", "обработка/вывод полей")
	utils.Command("sort", "сортировка строк")
	utils.Command("uniq", "удаление дубликатов (после sort)")
	utils.Command("head -n N", "первые N строк")
	utils.Command("tail -n N", "последние N строк")
	utils.Command("wc -l", "подсчёт строк")
	utils.Command("tr 'a-z' 'A-Z'", "замена символов")
	utils.Command("cut -d: -f1", "вырезать поле")
	fmt.Println()
	utils.Code(`# Практический пример — топ-5 процессов по памяти:
ps aux --sort=-%mem | head -6

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

# Подсчёт файлов по расширению:
find . -type f | sed 's/.*\.//' | sort | uniq -c | sort -rn`)

	utils.Footer()
}
