"""Generate deterministic synthetic service-visit backup sets."""
import hashlib,json,sqlite3,tarfile,io,shutil
from pathlib import Path
from restore_check import digest,FORMAT

def create(destination,snapshot='demo-2026-01',count=24):
 d=Path(destination);d.mkdir(parents=True,exist_ok=True)
 dbpath=d/'database.sqlite';dbpath.unlink(missing_ok=True)
 db=sqlite3.connect(dbpath)
 db.executescript('CREATE TABLE metadata(key TEXT PRIMARY KEY,value TEXT NOT NULL); CREATE TABLE visits(id INTEGER PRIMARY KEY,asset TEXT NOT NULL,status TEXT NOT NULL); CREATE TABLE documents(path TEXT PRIMARY KEY,visit_id INTEGER NOT NULL REFERENCES visits(id),sha256 TEXT NOT NULL,bytes INTEGER NOT NULL);')
 db.execute('INSERT INTO metadata VALUES (?,?)',('snapshot_id',snapshot))
 files=[]
 with tarfile.open(d/'files.tar','w') as tf:
  for i in range(1,count+1):
   db.execute('INSERT INTO visits VALUES (?,?,?)',(i,f'AHU-{i:03d}','complete' if i%3 else 'open'))
   data=f'{snapshot}\nVisit {i}\nAsset AHU-{i:03d}\nInspection notes: synthetic fixture.\n'.encode()
   name=f'visits/{i:03d}.txt';sha=hashlib.sha256(data).hexdigest();info=tarfile.TarInfo(name);info.size=len(data);info.mtime=0;info.mode=0o600;tf.addfile(info,io.BytesIO(data))
   db.execute('INSERT INTO documents VALUES (?,?,?,?)',(name,i,sha,len(data)));files.append({'path':name,'bytes':len(data),'sha256':sha})
 db.commit();db.close()
 m={'format':FORMAT,'snapshot_id':snapshot,'expected_visits':count,'database_sha256':digest(dbpath),'archive_sha256':digest(d/'files.tar'),'files':files}
 (d/'manifest.json').write_text(json.dumps(m,indent=2)+'\n')
 return d

def variants(base):
 base=Path(base);good=create(base/'good');other=create(base/'other','demo-2026-02')
 for name in ['corrupt','mixed-snapshot','missing-file']:
  out=base/name
  if out.exists():shutil.rmtree(out)
  shutil.copytree(good,out)
 corrupt=base/'corrupt';p=corrupt/'database.sqlite';p.write_bytes(p.read_bytes()[:100])
 mixed=base/'mixed-snapshot';shutil.copyfile(other/'database.sqlite',mixed/'database.sqlite')
 m=json.loads((mixed/'manifest.json').read_text());m['database_sha256']=digest(mixed/'database.sqlite');(mixed/'manifest.json').write_text(json.dumps(m,indent=2)+'\n')
 missing=base/'missing-file'
 with tarfile.open(good/'files.tar') as src,tarfile.open(missing/'files.tar','w') as dst:
  for i,member in enumerate(src):
   if i:dst.addfile(member,src.extractfile(member))
 m=json.loads((missing/'manifest.json').read_text());m['archive_sha256']=digest(missing/'files.tar');(missing/'manifest.json').write_text(json.dumps(m,indent=2)+'\n')
 shutil.rmtree(other)
if __name__=='__main__':variants(Path(__file__).parent/'fixtures')
