#!/usr/bin/python
from invirt.database import *
from invirt.config import structs as config
from invirt import authz

def accessList(m):
    people = set()
    people.update(authz.expandOwner(m.owner))
    if m.administrator is not None:
        people.update(authz.expandAdmin(m.administrator))
    return people

def refreshMachine(m):
    people = accessList(m)
    old_people = set(a.user for a in m.acl)
    for removed in old_people - people:
        ma = [x for x in m.acl if x.user == removed][0]
        session.delete(ma)
    for p in people - old_people:
        ma = MachineAccess(user=p)
        m.acl.append(ma)
        session.add(ma)

def refreshCache():
    session.begin()

    try:
        machines = Machine.query.all()
        for m in machines:
            refreshMachine(m)
        session.flush()

        # Update the admin ACL as well
        admin_acl = set(authz.expandAdmin(config.adminacl))
        old_admin_acl = set(a.user for a in Admin.query)
        for removed in old_admin_acl - admin_acl:
            old = Admin.query.filter_by(user=removed).first()
            session.delete(old)
        for added in admin_acl - old_admin_acl:
            a = Admin(user=added)
            session.add(a)
        session.flush()
    
        # Atomically execute our changes
        session.commit()
    except:
        # Failed! Rollback all the changes.
        session.rollback()
        raise

if __name__ == '__main__':
    connect()
    refreshCache()
