#!/bin/sh
set -eu
umask 077
for NODE_BIN in /opt/homebrew/opt/node@22/bin /usr/local/opt/node@22/bin; do
  if [ -x "$NODE_BIN/node" ]; then PATH="$NODE_BIN:$PATH"; break; fi
done
export PATH
command -v python3.12 >/dev/null 2>&1 || { echo 'Python 3.12 is required. On macOS: brew install python@3.12 node@22' >&2; exit 1; }
command -v node >/dev/null 2>&1 || { echo 'Node.js 22 is required. Install Node and retry.' >&2; exit 1; }
exec python3.12 - "$@" <<'SOPHIA_INSTALL_PYTHON'
import base64,hashlib,json,os,pathlib,platform,subprocess,sys,tarfile,tempfile,urllib.request,urllib.parse
CATALOG=json.loads(base64.b64decode('eyJwYXlsb2FkIjp7ImNoYW5uZWwiOiJzdGFibGUiLCJwcm9kdWN0Ijoic29waGlhLWJvdCIsInJlbGVhc2VzIjp7Im1hY29zLWFybTY0Ijp7Im1hbmlmZXN0X3NoYTI1NiI6IjE3ZmZkMjVhYzJjMDI0NDVhZTk0MTIxMmUzNTg1ZTk1NWYwN2M0MDBlMjgzNGMzMTZmZjgxOTkxNDU1ZTc3NGUiLCJzaGEyNTYiOiJjZjJlOGJlNjNiZTA2M2E4NjQ5NDEyODU0YTNkNDE4MDkzNDEzMWJiNjBmZDM0MjE3OTc3Yjc4YTZlY2UzNWUzIiwic2l6ZSI6MTc3MTI5NDksInVybCI6Imh0dHBzOi8vc29waGlhLWJvdC1kb3dubG9hZHMucGFnZXMuZGV2L2JvdC9yZWxlYXNlcy8wLjEzLjAvY2YyZThiZTYzYmUwNjNhODY0OTQxMjg1NGEzZDQxODA5MzQxMzFiYjYwZmQzNDIxNzk3N2I3OGE2ZWNlMzVlMy9zb3BoaWEtYm90LW1hY29zLWFybTY0LnRhci5neiJ9fSwic2NoZW1hIjoxLCJ2ZXJzaW9uIjoiMC4xMy4wIn0sInNpZ25hdHVyZSI6IjN0ZjBhT1ZsYWVRTGIrNW1nS2ZUZ0liakUyZHZya0k2NTRMNld4dmFrcXB5QS9TWWZyUkxSWmk4UXNIa1MzaHZnb2htWG9oVGNlVTJXYURTVWtCQUFRPT0ifQ=='))
BASE='https://sophia-bot-downloads.pages.dev/bot'
KEY_HASH='f67e7e3e944d1ec407c1ee94e0756af3496a007eab5ed211671cc1258180ab13'
target={('Darwin','arm64'):'macos-arm64',('Linux','x86_64'):'linux-x64',('Linux','aarch64'):'linux-arm64'}.get((platform.system(),platform.machine()))
entry=CATALOG['payload']['releases'].get(target)
if not entry: sys.exit('This release does not support your platform. No changes made.')
class Redirect(urllib.request.HTTPRedirectHandler):
 def redirect_request(self,req,fp,code,msg,headers,newurl):
  if urllib.parse.urlsplit(newurl).netloc != urllib.parse.urlsplit(BASE).netloc or not newurl.startswith('https://'): raise ValueError('Unsafe download redirect')
  return super().redirect_request(req,fp,code,msg,headers,newurl)
with tempfile.TemporaryDirectory(prefix='sophia-bot-install-') as folder:
 root=pathlib.Path(folder);archive=root/'release.tar.gz';dest=root/'unpacked';dest.mkdir()
 size=0;hasher=hashlib.sha256()
 request=urllib.request.Request(entry['url'],headers={'User-Agent':'sophia-bot-product/1','Accept-Encoding':'identity'})
 with urllib.request.build_opener(Redirect()).open(request,timeout=60) as response,archive.open('wb') as out:
  while True:
   chunk=response.read(1024*1024)
   if not chunk: break
   size+=len(chunk)
   if size>entry['size']: sys.exit('Archive exceeds expected size')
   hasher.update(chunk);out.write(chunk)
 if size!=entry['size'] or hasher.hexdigest()!=entry['sha256']: sys.exit('Download checksum failed; existing installation unchanged')
 with tarfile.open(archive,'r:gz') as tar:
  members=[];seen=set();total=0
  for m in tar:
   name=m.name.rstrip('/') if m.isdir() else m.name
   parts=name.split('/');total+=m.size
   if not name or name.startswith('/') or any(p in ('','..','.') for p in parts) or '\\' in name or ':' in name or any(ord(c)<32 for c in name) or name.casefold() in seen or not (m.isfile() or m.isdir()) or m.size<0 or total>2*1024**3 or len(members)>50000: sys.exit('Unsafe archive rejected')
   seen.add(name.casefold());members.append(m)
  tar.extractall(dest,members=members,filter='data')
 key=dest/'RELEASE-PUBLIC-KEY.pem'
 if hashlib.sha256(key.read_bytes()).hexdigest()!=KEY_HASH: sys.exit('Release key does not match installer')
 channel=root/'channel.json';channel.write_text(json.dumps(CATALOG))
 env=dict(os.environ,SOPHIA_BOT_DISTRIBUTION_URL=BASE,SOPHIA_BOT_RELEASE_PYTHON=sys.executable)
 subprocess.run([str(dest/'bin/sophia-bot'),'install','--archive',str(archive),'--catalog',str(channel),*sys.argv[1:]],env=env,check=True)
print('Installed at '+str(pathlib.Path.home()/'.local/bin/sophia-bot'))
print('Add ~/.local/bin to PATH if needed. Run sophia-bot to choose your local or cloud model. Updates: sophia-bot update')
SOPHIA_INSTALL_PYTHON
