// Package regionmedic detects and surgically repairs corrupted 7 Days to Die
// region (".7rg") files using the panel's own backups.
//
// Background
//
// 7DTD stores the world as a grid of 512×512-block "region" files, each
// holding a 32×32 grid of chunks. When the server process dies mid-save (a
// bare `docker stop` SIGKILL with no `saveworld`, an OOM kill, a crash) a
// region file can be left with a torn chunk: the chunk's bytes no longer begin
// with the expected header. On the next load 7DTD logs "Wrong chunk header!",
// writes an `error_backup_<cx>_<cz>` salvage file, and drops the chunk — so a
// base straddling the damaged region loses exactly the half that lived in it.
//
// This package reproduces, as deterministic code, the manual recovery that
// works: localize the damaged region(s) from the error_backup files, find the
// newest pre-corruption backup whose copy of that region validates clean,
// snapshot the corrupt live file, swap the clean copy in (in place, preserving
// permissions), and quarantine the error_backup salvage files.
//
// The .7rg on-disk format (reverse-engineered + verified byte-for-byte against
// real region files, see RE notes in the repo history):
//
//	Sector size  = 4096 bytes; file size is always a multiple of 4096.
//	Region       = 32×32 = 1024 chunks.
//	Sector 0     = header:  magic "7rg"+0x01 at 0x000; bytes 0x004..0xFFF zero.
//	Sector 1     = location table at 0x1000: 1024 entries × 4 bytes, each
//	               [3-byte little-endian sector offset][1-byte sector count];
//	               an absent chunk is 0x00000000. Table index = localX + localZ*32
//	               (X varies fastest). Chunk blob lives at sectorOffset*4096.
//	Chunk blob   = [u32 LE blockLength][12 bytes zero][magic "ttc\0"]
//	               [u32 LE const 47][raw DEFLATE stream].
//	               blockLength = 8 + len(deflate); the on-disk blob occupies
//	               16 + blockLength bytes, rounded up to whole sectors (the
//	               stored sector count may be one larger — allocator slack).
//	               The decompressed payload begins int32 chunkX, int32 0,
//	               int32 chunkZ.
//
// The "ttc\0" magic at blob offset 0x10 is the exact byte sequence 7DTD checks
// when it logs "Wrong chunk header!", so it is both what Validate flags and the
// minimal faithful corruption used by the test harness.
//
// Frozen API surface (do not break callers — the agent dispatch handler, the
// region-medic CLI, and the unit tests all depend on these signatures):
//
//	Validation:   ValidateRegionBytes, ValidateRegionFile -> RegionReport
//	Localize:     RegionCoord, RegionForChunk, ParseErrorBackup, ParseRegionFileName
//	Scan:         ScanRegionDir -> RegionDirScan / AffectedRegion
//	Backups:      BackupRef, ListPanelBackups, ExtractRegionFromBackup,
//	              FindLastGoodRegion -> Candidate
//	Heal:         PlanHeal -> HealPlan; ApplyHeal -> HealResult
//
// Everything here is pure (filesystem + archive/tar + compress/flate, stdlib
// only). It performs no Docker or network actions; orchestration (graceful
// save, stop, start, log-watch) is the caller's job, which keeps the decision
// logic fully unit-testable.
package regionmedic
