#!/usr/bin/env python3
"""
Дедупликация бэкапов D:\\irelyinstall\\backup:
- нормализация имени: убрать префикс 'Jenkins4_', хвост '_backup_MMDDYYYY' / '_MMDDYYYY' / '_0614026'
- слияние опечаточных вариантов (одинаковый размер/дата или продолжение размерного ряда)
- в каждой группе оставить самую свежую копию по СТОЛБЦУ ДАТЫ (tie-break: больший размер)
Источник: /root/.hermes/profiles/irelydata/pastes/paste_1_133330.txt
"""
import re
import csv
from datetime import datetime
from pathlib import Path

SRC = Path("/root/.hermes/profiles/irelydata/pastes/paste_1_133330.txt")
OUT_CSV = Path("/root/ir-assessment/redteam/irelydata/dirlists/backups_latest_only.csv")
OUT_MD = Path("/root/ir-assessment/redteam/irelydata/dirlists/backups_latest_only.md")

# Ручные слияния опечаточных/вариантных имён (подтверждены размером и датами)
MERGE = {
    "2610PAMDALEUAP0": "2610PAMDALEUAP01",        # одинаковый размер 1,771,166,208, одна дата, разница 3 мин
    "2710PALMDALEOILUAP011": "2710PALMDALEOILUAP01",  # продолжение размерного ряда 1.96->2.03->2.10 GB
}

pat = re.compile(r"^(\d{2}/\d{2}/\d{4})\s+(\d{2}:\d{2}\s+[AP]M)\s+([\d,]+)\s+(.+?)\s*$")
# хвосты даты в имени: _backup_11172025, _01232025, _0614026, _251112
tail = re.compile(r"(_backup)?_\d{6,8}$")

rows = []
with SRC.open(encoding="utf-8", errors="replace") as f:
    for line in f:
        m = pat.match(line.rstrip("\n"))
        if not m:
            continue
        d, t, size, name = m.groups()
        dt = datetime.strptime(f"{d} {t}", "%m/%d/%Y %I:%M %p")
        rows.append((dt, int(size.replace(",", "")), name))

assert len(rows) == 66, f"ожидалось 66 строк, получили {len(rows)}"

groups = {}
for dt, size, name in rows:
    stem, dot, ext = name.rpartition(".")
    base = stem
    if base.startswith("Jenkins4_"):
        base = base[len("Jenkins4_"):]
    base = tail.sub("", base)
    base = MERGE.get(base, base)
    key = f"{base}.{ext}"
    groups.setdefault(key, []).append((dt, size, name))

latest = []
for key, items in groups.items():
    # самая свежая по дате; при равенстве дат — больший размер
    best = max(items, key=lambda r: (r[0], r[1]))
    latest.append((best[0], best[1], best[2], key, len(items), sum(s for _, s, _ in items)))

latest.sort(key=lambda r: r[0], reverse=True)  # свежие сверху

total_orig = sum(s for _, s, _ in rows)
total_dedup = sum(r[1] for r in latest)

print(f"Исходных файлов: {len(rows)} ({total_orig:,} bytes = {total_orig/1024**3:.1f} GB)")
print(f"Уникальных бэкапов (последняя версия): {len(latest)} ({total_dedup:,} bytes = {total_dedup/1024**3:.1f} GB)")
print(f"Экономия: {(total_orig-total_dedup)/1024**3:.1f} GB ({100*(total_orig-total_dedup)/total_orig:.0f}%)")
print()
hdr = f"{'#':>2}  {'Дата копии':<16}  {'Размер':>16}  {'GB':>6}  {'Версий':>6}  Имя файла (последняя версия)"
print(hdr)
print("-" * len(hdr) + "-----------")
for i, (dt, size, name, key, nver, _) in enumerate(latest, 1):
    print(f"{i:>2}  {dt.strftime('%Y-%m-%d %H:%M'):<16}  {size:>16,}  {size/1024**3:>6.1f}  {nver:>6}  {name}")

# Сохраняем CSV + MD
with OUT_CSV.open("w", newline="", encoding="utf-8") as f:
    w = csv.writer(f)
    w.writerow(["n", "date_column", "size_bytes", "size_gb", "versions_in_group", "latest_filename", "group_key"])
    for i, (dt, size, name, key, nver, _) in enumerate(latest, 1):
        w.writerow([i, dt.strftime("%Y-%m-%d %H:%M"), size, f"{size/1024**3:.1f}", nver, name, key])

with OUT_MD.open("w", encoding="utf-8") as f:
    f.write("# D:\\irelyinstall\\backup — только последние версии бэкапов\n\n")
    f.write(f"Дата анализа: {datetime.now().strftime('%Y-%m-%d %H:%M')}\n\n")
    f.write(f"- Исходных файлов: **{len(rows)}** ({total_orig/1024**3:.1f} GB)\n")
    f.write(f"- После дедупликации: **{len(latest)}** ({total_dedup/1024**3:.1f} GB)\n")
    f.write(f"- Экономия: **{(total_orig-total_dedup)/1024**3:.1f} GB**\n\n")
    f.write("Отбор: группировка по базовому имени (без `Jenkins4_` и хвостовой даты), ")
    f.write("в группе — копия с максимальной датой из СТОЛБЦА ДАТЫ.\n\n")
    f.write("Слитые опечаточные варианты:\n")
    f.write("- `2610PAMDALEUAP0_11192025.bak` -> `2610PAMDALEUAP01` (идентичный размер, одна дата)\n")
    f.write("- `2710PALMDALEOILUAP011_09112026.bak` -> `2710PALMDALEOILUAP01` (продолжение размерного ряда)\n\n")
    f.write("| # | Дата копии | Размер | GB | Версий в группе | Файл |\n")
    f.write("|---|------------|--------|----|-----------------|------|\n")
    for i, (dt, size, name, key, nver, _) in enumerate(latest, 1):
        f.write(f"| {i} | {dt.strftime('%Y-%m-%d %H:%M')} | {size:,} | {size/1024**3:.1f} | {nver} | `{name}` |\n")

print(f"\nСохранено: {OUT_CSV}")
print(f"Сохранено: {OUT_MD}")
