package linuxmodules

import (
	"fmt"
	"rubric/utils"
)

var ScriptsModule = Module{
	Key:         "scripts",
	Aliases:     []string{"sc", "scripting", "скрипты"},
	Title:       "Bash-скрипты",
	Description: "Темы 27–32: скрипты, условия, циклы, функции, массивы",
	Run:         showScripts,
}

func showScripts() {
	utils.Header("Linux — Bash-скрипты")

	// ─── 27. Bash скрипты №1 ──────────────────────────────────────
	utils.Section("27. Основы скриптов. Условия")

	utils.Println(utils.ColorBold + "Структура скрипта:" + utils.ColorReset)
	utils.Code(`#!/bin/bash
# Shebang — первая строка указывает интерпретатор
# Комментарий

echo "Привет, мир!"

# Запуск скрипта:
chmod +x script.sh     # сделать исполняемым
./script.sh            # запустить
bash script.sh         # запустить через bash (без chmod)`)

	utils.Println(utils.ColorBold + "Переменные в скриптах:" + utils.ColorReset)
	utils.Code(`#!/bin/bash
name="Alice"
count=5

echo "Имя: $name"
echo "Счёт: $count"

# Ввод от пользователя:
read -p "Введите имя: " username
echo "Привет, $username!"

# Ввод без отображения (пароль):
read -s -p "Пароль: " password`)

	utils.Println(utils.ColorBold + "Условный оператор if:" + utils.ColorReset)
	utils.Code(`#!/bin/bash
# Базовая форма:
if [ условие ]; then
    команды
elif [ другое_условие ]; then
    команды
else
    команды
fi

# Примеры условий:
# Сравнение строк:
if [ "$name" = "Alice" ]; then echo "Привет, Alice"; fi
if [ "$name" != "Bob" ]; then echo "Не Боб"; fi
if [ -z "$name" ]; then echo "Пустая строка"; fi    # -z = пусто
if [ -n "$name" ]; then echo "Не пустая"; fi         # -n = не пусто

# Сравнение чисел:
if [ "$count" -eq 5 ]; then ...   # equal
if [ "$count" -ne 5 ]; then ...   # not equal
if [ "$count" -gt 3 ]; then ...   # greater than
if [ "$count" -lt 10 ]; then ...  # less than
if [ "$count" -ge 5 ]; then ...   # greater or equal
if [ "$count" -le 5 ]; then ...   # less or equal

# Файлы и директории:
if [ -f /etc/passwd ]; then echo "файл существует"; fi
if [ -d /tmp ]; then echo "директория существует"; fi
if [ -e /dev/sda ]; then echo "путь существует"; fi
if [ -r file ]; then echo "доступен для чтения"; fi
if [ -w file ]; then echo "доступен для записи"; fi
if [ -x script.sh ]; then echo "исполняемый"; fi
if [ -s file ]; then echo "файл не пустой"; fi
if [ file1 -nt file2 ]; then echo "file1 новее"; fi

# Логика:
if [ cond1 ] && [ cond2 ]; then ...   # И
if [ cond1 ] || [ cond2 ]; then ...   # ИЛИ
if ! [ cond ]; then ...               # НЕ

# [[ ]] — расширенные условия bash:
if [[ "$str" == *"подстрока"* ]]; then ...   # glob
if [[ "$str" =~ ^[0-9]+$ ]]; then ...        # regex`)

	// ─── 28–29. Bash скрипты №2–3 ─────────────────────────────────
	utils.Section("28–29. Циклы")

	utils.Println(utils.ColorBold + "Цикл for:" + utils.ColorReset)
	utils.Code(`# По списку:
for item in один два три; do
    echo "$item"
done

# По числовому диапазону:
for i in {1..5}; do
    echo "Шаг $i"
done

# С шагом:
for i in {0..20..5}; do echo "$i"; done   # 0 5 10 15 20

# C-стиль:
for ((i=0; i<5; i++)); do
    echo "$i"
done

# По файлам:
for file in /etc/*.conf; do
    echo "Обрабатываю: $file"
done

# По строкам вывода команды:
for user in $(cat /etc/passwd | cut -d: -f1); do
    echo "Пользователь: $user"
done`)

	utils.Println(utils.ColorBold + "Цикл while:" + utils.ColorReset)
	utils.Code(`# Пока условие истинно:
count=0
while [ $count -lt 5 ]; do
    echo "count = $count"
    ((count++))
done

# Чтение файла построчно:
while IFS= read -r line; do
    echo "Строка: $line"
done < /etc/hosts

# Бесконечный цикл:
while true; do
    echo "Работаю..."
    sleep 1
done`)

	utils.Println(utils.ColorBold + "Цикл until и управление циклами:" + utils.ColorReset)
	utils.Code(`# Пока условие ложно:
until [ -f /tmp/ready ]; do
    echo "Жду файл..."
    sleep 1
done

# break — выйти из цикла:
for i in {1..10}; do
    if [ $i -eq 5 ]; then break; fi
    echo $i
done

# continue — перейти к следующей итерации:
for i in {1..10}; do
    if [ $((i % 2)) -eq 0 ]; then continue; fi
    echo "Нечётное: $i"
done`)

	// ─── 30–31. Bash скрипты №4–5 ─────────────────────────────────
	utils.Section("30–31. Функции и обработка ошибок")

	utils.Println(utils.ColorBold + "Функции:" + utils.ColorReset)
	utils.Code(`#!/bin/bash
# Объявление функции:
greet() {
    local name=$1       # local — локальная переменная
    echo "Привет, $name!"
}

# Или:
function greet {
    echo "Привет, $1!"
}

# Вызов:
greet "Alice"
greet "Bob"

# Возвращаемое значение:
# Функции возвращают только числа (код возврата 0-255)
is_root() {
    [ "$(id -u)" -eq 0 ]
}

if is_root; then
    echo "Запущен как root"
fi

# Для передачи строк — echo + подстановка команд:
get_hostname() {
    echo "$(hostname)"
}
host=$(get_hostname)`)

	utils.Println(utils.ColorBold + "Обработка ошибок:" + utils.ColorReset)
	utils.Code(`#!/bin/bash
# Остановить при ошибке:
set -e          # выйти при любой ошибке (exit on error)
set -u          # ошибка при неопределённой переменной
set -o pipefail # учитывать ошибки в pipe
set -euo pipefail  # всё вместе (рекомендуется)

# Проверка кода возврата:
if ! mkdir /tmp/mydir 2>/dev/null; then
    echo "Ошибка создания директории" >&2
    exit 1
fi

# Функция для вывода ошибок:
error() {
    echo "ОШИБКА: $*" >&2
    exit 1
}

[ -f "$1" ] || error "Файл $1 не найден"

# Trap — обработка сигналов и выхода:
cleanup() {
    rm -f /tmp/tempfile
    echo "Очищено"
}
trap cleanup EXIT           # при любом выходе
trap cleanup INT TERM       # при Ctrl+C или kill`)

	// ─── 32. Bash скрипты №6 ──────────────────────────────────────
	utils.Section("32. Массивы, строки и аргументы скрипта")

	utils.Println(utils.ColorBold + "Массивы:" + utils.ColorReset)
	utils.Code(`# Объявление:
fruits=("яблоко" "банан" "апельсин")
declare -a numbers=(1 2 3 4 5)

# Доступ:
echo "${fruits[0]}"          # яблоко (индекс с 0)
echo "${fruits[@]}"          # все элементы
echo "${#fruits[@]}"         # количество элементов
echo "${fruits[@]:1:2}"      # срез: с индекса 1, 2 элемента

# Добавить элемент:
fruits+=("манго")

# Перебор:
for fruit in "${fruits[@]}"; do
    echo "$fruit"
done

# Перебор с индексом:
for i in "${!fruits[@]}"; do
    echo "$i: ${fruits[$i]}"
done

# Ассоциативный массив (словарь):
declare -A user
user[name]="Alice"
user[age]=30
echo "${user[name]}"
echo "${!user[@]}"    # ключи
echo "${user[@]}"     # значения`)

	utils.Println(utils.ColorBold + "Аргументы скрипта:" + utils.ColorReset)
	utils.Code(`#!/bin/bash
# Позиционные параметры:
echo "Скрипт: $0"
echo "Первый аргумент: $1"
echo "Второй аргумент: $2"
echo "Все аргументы: $@"
echo "Количество аргументов: $#"

# Проверка аргументов:
if [ $# -lt 2 ]; then
    echo "Использование: $0 <имя> <возраст>" >&2
    exit 1
fi

# Обработка опций (getopts):
while getopts "hv:n:" opt; do
    case $opt in
        h) echo "Справка"; exit 0 ;;
        v) verbose=true ;;
        n) name="$OPTARG" ;;
        ?) echo "Неизвестный ключ"; exit 1 ;;
    esac
done

# shift — сдвинуть аргументы:
shift $((OPTIND - 1))   # убрать опции, остались обычные аргументы`)

	utils.Println(utils.ColorBold + "Полезные приёмы:" + utils.ColorReset)
	utils.Code(`# Цвета в терминале:
RED='\033[0;31m'
GREEN='\033[0;32m'
NC='\033[0m'   # No Color
echo -e "${RED}Ошибка${NC}"
echo -e "${GREEN}Успех${NC}"

# Прогресс-бар простой:
for i in {1..10}; do
    echo -ne "\rПрогресс: $((i*10))%"
    sleep 0.1
done; echo

# Логирование:
LOG=/var/log/myscript.log
log() { echo "[$(date '+%Y-%m-%d %H:%M:%S')] $*" | tee -a "$LOG"; }
log "Скрипт запущен"

# Ожидание с таймаутом:
timeout 30 ./long_command.sh || echo "Таймаут!"`)
	fmt.Println()
	utils.Note("Проверяйте скрипты на ошибки: bash -n script.sh (синтаксис) и bash -x script.sh (трассировка).")

	utils.Footer()
}
