"""Build a source release with a SHA-256 inventory; excludes runtime secrets and data."""
from pathlib import Path
import hashlib, os, sys, zipfile
root=Path(__file__).resolve().parent.parent
out=Path(sys.argv[1]).resolve() if len(sys.argv)>1 else root.parent/'zentrikhrms-6.2.0.zip'
if out.parent!=root.parent: raise SystemExit('Choose a filename in the parent outputs directory.')
excluded={'.git','.codex','vendor','node_modules','test-results','playwright-report','work'}
files=[]
for base,dirs,names in os.walk(root,followlinks=False):
 dirs[:]=sorted(d for d in dirs if d not in excluded and not (Path(base)/d).is_symlink())
 for name in sorted(names):
  f=Path(base)/name;rel=f.relative_to(root).as_posix()
  if rel.startswith('storage/') and name!='.gitignore':continue
  if f.is_symlink() or name=='.env' or (name.startswith('.env.') and name not in {'.env.example','.env.production.example'}):continue
  if f.suffix.lower() in {'.pem','.key','.log','.sqlite','.sqlite3','.db','.sql','.encrypted','.zip'}:continue
  if name.lower().endswith(('.sqlite-wal','.sqlite-shm','.sqlite-journal','.db-wal','.db-shm','.db-journal','.sql.gz','.sql.bak')):continue
  if rel.startswith('bootstrap/cache/') and name!='.gitignore':continue
  if rel=='public/hot' or name=='.phpunit.result.cache':continue
  files.append((f,rel))
inventory=[]
with zipfile.ZipFile(out,'x',zipfile.ZIP_DEFLATED,compresslevel=6) as z:
 for f,rel in files:
  data=f.read_bytes();inventory.append(hashlib.sha256(data).hexdigest()+'  '+rel);z.writestr(rel,data)
 z.writestr('SHA256SUMS.txt','\n'.join(inventory)+'\n')
digest=hashlib.sha256(out.read_bytes()).hexdigest()
out.with_suffix('.zip.sha256').write_text(digest+'  '+out.name+'\n',encoding='utf-8')
print(f'Release archive: {out.name}; files: {len(files)}; SHA256: {digest}')
