# План реалізації: Traceroute та автоматична діагностика обривів

## Огляд
Цей план передбачає реалізацію функціоналу Traceroute для визначення маршруту до хоста та автоматичного виявлення точки обриву зв'язку шляхом опитування проміжних вузлів. Використовуватимуться системні утиліти (`traceroute` на Linux та `tracert` на Windows) для побудови початкової карти маршруту, а потім вбудований асинхронний механізм пінгування для діагностики конкретних хопів.

## Зміни в архітектурі

### 1. Модель даних (`src/model/status.rs` та `src/model/app_state.rs`)
- **Unified Ping Pool**: Перехід від пінгування "списку хостів" до пінгування "унікальних адрес".
- `AppState.statuses: HashMap<String, HostStatus>` — тепер міститиме статуси як для основних хостів, так і для проміжних вузлів (хопів).
- Додати до `HostStatus`:
    - `is_trace_hop: bool` — чи є цей вузол лише частиною маршруту.
    - `dependent_targets: HashSet<String>` — список цільових адрес, які проходять через цей вузол.
    - `failure_point_for: Vec<String>` — список цілей, для яких цей вузол став точкою обриву.

### 2. Логіка пінгування та керування навантаженням (`src/logic/pinger.rs`)
- **Розрахунок інтервалу (Priority Logic)**:
    - Якщо адреса є **цільовим хостом** — використовувати обраний користувачем режим (наприклад, 2с).
    - Якщо адреса є **лише хопом** — використовувати пасивний режим (наприклад, 30с або 60с), щоб мати актуальну картину маршруту без перевантаження мережі.
    - **Режим діагностики**: Якщо хоча б одна ціль, що залежить від цього хопа, перейшла в статус `DOWN`, інтервал для хопа тимчасово зменшується до 2с (Fast) для точної локалізації обриву.
- **Дедуплікація**: Один фізичний роутер пінгується лише один раз за цикл, навіть якщо він входить у 10 різних маршрутів.

### 3. Логіка трасування (`src/logic/tracer.rs`)
- Періодичне виконання `traceroute -n`/`tracert -d` (раз на 1 годину або при зміні мережі).
- Оновлення `traceroute_path` для цілі та реєстрація нових хопів у глобальному пулі `statuses`.

### 4. Запобіжники та валідація обривів (Safeguards)
Для уникнення хибних спрацювань через перевантаження роутерів або ICMP Rate Limiting:
- **Поріг "існування" (At least one rule)**: Вузол не вважається точкою обриву, якщо ми отримуємо хоча б одну відповідь з останніх 3-5 пакетів. Це дозволяє розрізняти "обрив" (100% loss) та "перевантаження" (частковий loss).
- **Кореляція "Downstream"**: Вузол $N$ розглядається як потенційний обрив лише тоді, коли він сам **і всі наступні вузли** (включаючи ціль) демонструють критичну втрату пакетів протягом останнього вікна спостереження.
- **Підтвердження серією (Streak Validation)**: Точка обриву фіксується лише після серії з 3-5 послідовних невдач для всього ланцюжка після цього вузла. Поодинокі втрати на роутерах ігноруються.
- **Двофазна перевірка**: Коли виявлено підозру на обрив, програма надсилає "контрольну серію" з 5 швидких пінгів. Якщо хоча б 1 повертається — обриву немає, є перевантаження.

## Етапи реалізації

### Етап 1: Уніфікація Pinger Task та моделі даних
- [x] Оновити `HostStatus`: додати `traceroute_path`, `is_hop`, `dependent_targets`.
- [x] Рефакторинг `pinger_task`: ітерація по унікальним IP-адресам.
- [x] Реалізувати `effective_mode_for(address)` з врахуванням діагностичного стану.

### Етап 2: Модуль трасування та парсингу
- [x] Реалізувати `run_traceroute` (Linux: `traceroute -n`, Windows: `tracert -d`).
- [x] Написати тести на парсинг виводу різних систем.

### Етап 3: Алгоритм дедукції обриву (Safeguards)
- [x] Реалізувати логіку `find_break_point`:
    - Прохід по маршруту від найближчого до найдальшого вузла.
    - Перевірка умови: `!node.alive && !any_further_node.alive`.
    - Врахування `streak` для фільтрації одиничних втрат.
- [x] Додати "контрольний цикл" пінгування при підозрі на обрив.

### Етап 4: UI та візуалізація
- [x] Додати індикатор 📍 біля кожного хоста.
- [x] При кліку — показувати ієрархічний список хопів.
- [x] Візуальне виділення `failure_point` з поясненням (напр. "Confirmed after 3 retries").

## Етапи реалізації

### Етап 1: Модуль трасування та парсингу
- [ ] Створити `src/logic/tracer.rs`.
- [ ] Реалізувати виконання команд:
    - Linux: `traceroute -n -m 30 -q 1 <address>`
    - Windows: `tracert -d -h 30 <address>`
- [ ] Додати регулярний вираз для витягування IP-адрес хопів зі стандартного виводу.
- [ ] Написати модульні тести з прикладами реального виводу (англійська, українська локалі Windows, різні дистрибутиви Linux).

### Етап 2: Оновлення моделей
- [ ] Додати поля `traceroute_path`, `failure_point` тощо до `HostStatus` у `src/model/status.rs`.
- [ ] Оновити методи серіалізації (пропускати ці поля при збереженні, крім можливо `traceroute_path`).

### Етап 3: Інтеграція в Pinger Task
- [ ] У `pinger_task` додати перевірку: якщо хост щойно доданий або `last_traceroute` застарів (> 1 год), запустити фонове трасування.
- [ ] Реалізувати реакцію на DOWN:
    - Якщо `alive == false`, запустити швидкий цикл пінгу по `traceroute_path`.
    - Оновити `failure_point` результатом.
- [ ] Забезпечити асинхронність — діагностика одного хоста не повинна блокувати пінгування інших.

### Етап 4: Інтерфейс (UI)
- [ ] Додати кнопку 📍 (або піктограму маршруту) в рядок хоста.
- [ ] Реалізувати випадаюче вікно або тултіп з переліком хопів.
- [ ] Якщо хост DOWN і знайдено точку обриву — показувати її червоним кольором поруч зі статусом DOWN (наприклад: `DOWN (at 192.168.1.1)`).

## Обробка локалі та варіацій
- **Numeric-only mode**: Використання `-n` (Linux) та `-d` (Windows) змушує утиліти виводити лише IP-адреси, що робить парсинг незалежним від мови системи або проблем з DNS-резолвінгом імен проміжних вузлів.
- **Відсутність утиліти**: Якщо `traceroute` не знайдено в системі, програма повинна коректно це обробити (залишити список хопів порожнім).

## Критерії успіху
- [ ] Програма успішно будує список хопів для `google.com`.
- [ ] При імітації обриву (наприклад, пінг неіснуючої внутрішньої адреси за шлюзом) програма коректно вказує на шлюз або перший недоступний вузол.
- [ ] Тести парсингу проходять для виводу Windows `tracert` та Linux `traceroute`.
- [ ] Програма залишається стабільною і не споживає зайвих ресурсів при тривалій роботі.
