#!/usr/bin/python3
"""Launch a per-user updatable copy of the system-installed Thunder seed."""
import fcntl, json, os, pathlib, shutil, sys, tempfile
def version(root):
    for name in ['installed-update.json','BUILD.json']:
        try:
            value=json.loads((root/name).read_text())['version']
            return tuple(int(n) for n in value.split('-')[0].split('.'))
        except (OSError,ValueError,KeyError,TypeError):pass
    return ()
def prepare(seed, base):
 app=base/'app'
 base.mkdir(parents=True,exist_ok=True)
 with (base/'.seed.lock').open('w') as lock:
    fcntl.flock(lock,fcntl.LOCK_EX)
    if not (app/'thunder').exists():
        staging=pathlib.Path(tempfile.mkdtemp(prefix='.seed-',dir=base))
        shutil.copytree(seed,staging,dirs_exist_ok=True)
        os.rename(staging,app)
    elif version(seed)>version(app):
        # The Debian seed can advance, but must never roll back a newer in-app update.
        # Running processes keep their previous inode; each replaced file is atomic.
        for name in ['thunder','bulletin-studio','BUILD.json']:
            fd,path=tempfile.mkstemp(prefix='.seed-file-',dir=app);os.close(fd)
            shutil.copy2(seed/name,path);os.replace(path,app/name)
        previous=app/'installed-update.json'
        if previous.exists(): previous.rename(app/'installed-update.before-package.json')
    for name in ['thunder','bulletin-studio']:
        (app/name).chmod(0o755)
 return app

if __name__=='__main__':
    seed=pathlib.Path('/opt/thunder/seed')
    base=pathlib.Path(os.environ.get('XDG_DATA_HOME',str(pathlib.Path.home()/'.local/share')))/'thunder'
    app=prepare(seed,base);os.chdir(app)
    program='bulletin-studio' if '--studio' in sys.argv[1:] else 'thunder'
    os.execv(str(app/program),[str(app/program)])
