#!/usr/bin/env python3
r"""
Сравнение: примонтированные БД (sys.databases + sys.master_files) vs файлы D:\i21SQLData.
Источники:
- master_files.txt (sys.master_files, снят live 2026-09-12)
- i21sqldata_listing_with_sizes.txt (dir /s листинг с сервера 09/11)
"""
import re
from pathlib import Path

BASE = Path("/root/ir-assessment/redteam/irelydata/dirlists")

# --- 1. Примонтированные БД из sys.master_files ---
mounted = {}   # db -> {type: [(file, size_gb)]}
for line in (BASE / "master_files.txt").read_text().splitlines():
    parts = line.strip().split("|")
    if len(parts) != 4 or parts[0] in ("db", ""):
        continue
    db, typ, path, size = parts
    mounted.setdefault(db, []).append((typ, path, float(size)))

# --- 2. Файлы из dir-листинга i21SQLData ---
pat = re.compile(r"^\d{2}/\d{2}/\d{4}\s+\d{2}:\d{2}\s+[AP]M\s+([\d,]+)\s+(.+?)\s*$")
disk_files = {}  # filename_lower -> (name, size)
for line in (BASE / "i21sqldata_listing_with_sizes.txt").read_text(encoding="utf-8", errors="replace").splitlines():
    m = pat.match(line.strip())
    if m:
        size, name = m.groups()
        disk_files[name.lower()] = (name, int(size.replace(",", "")))

# --- 3. Сравнение ---
print("=" * 90)
print("A. Примонтированные БД и расположение их файлов")
print("=" * 90)
in_i21sqldata = []
outside_i21sqldata = []
for db, files in sorted(mounted.items()):
    for typ, path, sz in files:
        if typ == "ROWS":
            (in_i21sqldata if "\\i21sqldata\\" in path.lower() else outside_i21sqldata).append((db, path, sz))

print(f"\nБД с данными в D:\\i21SQLData: {len(in_i21sqldata)}")
print(f"\nБД с файлами ВНЕ D:\\i21SQLData ({len(outside_i21sqldata)}):")
for db, path, sz in outside_i21sqldata:
    print(f"    {db:<28} {sz:>8.2f} GB  {path}")

# --- 4. Все ли файлы из dir-листинга принадлежат примонтированным БД? ---
# ВНИМАНИЕ: пути Windows с backslash — Path() на Linux их не парсит, только ntpath/сплит по "\\"
import ntpath
mounted_files_lower = {ntpath.basename(p).lower() for _, fl in mounted.items() for _, p, _ in fl}
orphans_on_disk = [(n, s) for k, (n, s) in disk_files.items() if k not in mounted_files_lower]
print(f"\n" + "=" * 90)
print(f"B. Файлы в D:\\i21SQLData, НЕ принадлежащие примонтированным БД ({len(orphans_on_disk)})")
print("=" * 90)
for n, s in sorted(orphans_on_disk, key=lambda x: -x[1]):
    print(f"    {n:<45} {s/1024**3:>8.2f} GB")

# --- 5. Итоговая инвентаризация для плана бэкапов ---
print(f"\n" + "=" * 90)
print("C. Итог: что бэкапить")
print("=" * 90)
user_dbs = [db for db in mounted if db not in ("master", "model", "msdb", "tempdb")]
sys_dbs = [db for db in mounted if db in ("master", "model", "msdb", "tempdb")]
total_user_gb = 0.0
print(f"\nПользовательских БД примонтировано: {len(user_dbs)}")
print(f"Системных: {sorted(sys_dbs)}")
for db in sorted(user_dbs):
    rows_gb = sum(sz for typ, _, sz in mounted[db] if typ == "ROWS")
    total_user_gb += rows_gb
    print(f"    {db:<30} {rows_gb:>8.2f} GB (data)")
print(f"\nСуммарный размер данных пользовательских БД: {total_user_gb:.1f} GB")
