'''
Created on Apr 8, 2014

@author: mandy
'''
from rbacpolicy import *
import string
from ComputeSpecInfo import ComputeSpecInfo
from UserNode import UserNode

class DiagramIOHelper(object):
    def __init__(self, main):
        self.main = main
    
    def import_(self, specFileDir):
        return rbacpolicy(specFileDir)
        
    def export(self, specFileDir):
        self.main.specDialog.reGenerateSpec()
        spec = self.main.specDialog.ui.specTextEdit.toPlainText()
        with open(specFileDir, 'w') as f:
            lines  = spec.split('\n')
            for l in lines:
                f.write('%s\n'% l)
        f.close()
    
    def write(self, visFileDir):
        userList = self.main.userList
        roleList = self.main.roleList
        dirList = self.main.dirList

        tableUserRole = {}
        tableRolePerm = {}
        model = self.main.tableView.tableViewRoleUser.model()
        numRows = model.rowCount()
        numColumns = model.columnCount()
        for i in xrange(numRows):
            for j in xrange(numColumns):
                content = str(model.data(model.index(i,j)).toString())
                if content != '':
                    tableUserRole[(i,j)] = content
                    
        model = self.main.tableView.tableViewRolePerm.model()
        numRows = model.rowCount()
        numColumns = model.columnCount()
        for i in xrange(numRows):
            for j in xrange(numColumns):
                recursive = 0
                content = str(model.data(model.index(i,j)).toString())
                if content.find('-r') != -1:
                    recursive = 1
                    content = content.replace('-r', '')
                    content = content.replace('|', '')
                    content= content.replace(' ', '')
                if content != '':
                    tableRolePerm[(i,j)] = (content, recursive)
                              
        with open(visFileDir, 'w') as f:
            temp = ''
            temp = '$'.join(userList)
            f.write(temp+'\n')
            temp = '$'.join(roleList)
            f.write(temp+'\n')
            temp = '$'.join(dirList)
            f.write(temp+'\n')
            
            for k, v in tableUserRole.iteritems():
                f.write('MUR$%d$%d$%s\n' % (k[0], k[1], v))
            
            for k, v in tableRolePerm.iteritems():
                f.write('MRP$%d$%d$%s$%s\n' % (k[0], k[1], v[0], v[1]))
            
            for r in self.main.roleCompactNodes:
                if r.parents==set():
                    parents='None'
                else:
                    parents=','.join(r.parents)
                if r.children==set():
                    children='None'
                else:
                    children=','.join(r.children)
                f.write('RCompact$%s$%f$%f$%s$%s\n' % (r.name, r.relativeX, r.relativeY, parents, children))
                
            for r in self.main.roleNodes:
                f.write('R$%s$%f$%f\n' % (r.name, r.relativeX, r.relativeY))
            
            for u in self.main.userNodes:
                if u.roleNode == None:
                    f.write('FU$%s$%f$%f\n'%(u.name, u.relativeX, u.relativeY))
                    
            for d in self.main.dirNodes:
                f.write('D$%s$%f$%f\n' % (d.dir, d.relativeX, d.relativeY))
        f.close()
        
    def read(self, visFileDir):
        userRoleMat = self.main.user_role_mat
        roleResMat = self.main.role_res_mat
        roleHierMat = self.main.role_adjmat
        roleNodePos = {}
        roleCompactNodePos = {}
        freeuserNodePos = {}
        dirNodePos = {}
        
        with open(visFileDir, 'r') as f:
            line = f.readline()
            line = line.strip('\n')
            self.main.userList=line.split('$')
            self.main.userSet=set(self.main.userList)
            self.main.numUsers=len(self.main.userList)
            line = f.readline()
            line = line.strip('\n')
            self.main.roleList=line.split('$')
            self.main.roleSet=set(self.main.roleList)
            self.main.numRoles=len(self.main.roleList)

            line = f.readline()
            line = line.strip('\n')
            self.main.dirList=line.split('$')
            self.main.dirSet=set(self.main.dirList)
            self.main.numDirs=len(self.main.dirList)
                
            for line in f:
                line = line.strip('\n')
                components = string.split(line, '$')
                if components[0] == 'MUR':
                    row = int(components[1])
                    column = int(components[2])
                    user = self.main.userList[row]
                    role = self.main.roleList[column]
                    if user not in userRoleMat.keys():
                        userRoleMat[user] = set([role])
                    else:
                        userRoleMat[user].add(role)
                elif components[0] == 'MRP':
                    row = int(components[1])
                    column = int(components[2])
                    role = self.main.roleList[row]
                    dirc = self.main.dirList[column]
                    perms = set(components[3].split(','))
                    if components[4] == '0':
                        recursive = False
                    else:
                        recursive = True
                    if role not in roleResMat.keys():
                        roleResMat[role] = {dirc: makepermset(perms, recursive)}
                    else:
                        roleResMat[role][dirc] = makepermset(perms, recursive)
                elif components[0] == 'RCompact':
                    role = components[1]
                    relativeX, relativeY = float(components[2]), float(components[3])
                    if components[4] == 'None':
                        parents = set()
                    else:
                        parents = set(components[4].split(','))
                    if components[5] == 'None':
                        children = set()
                    else:
                        children = set(components[5].split(','))
                    if parents or children:
                        roleHierMat[role] = makerolenode(parents, children)
                    roleCompactNodePos[role] = (relativeX, relativeY)
                elif components[0] == 'R':
                    role = components[1]
                    relativeX, relativeY = float(components[2]), float(components[3])
                    roleNodePos[role] = (relativeX, relativeY)
                elif components[0] == 'FU':
                    user = components[1]
                    relativeX, relativeY = float(components[2]), float(components[3])
                    freeuserNodePos[user] = (relativeX, relativeY)
                elif components[0] == 'D':   
                    dirc = components[1]
                    relativeX, relativeY = float(components[2]), float(components[3])
                    dirNodePos[dirc] = (relativeX, relativeY)
        f.close()
        self.main.computeSpec = ComputeSpecInfo(self.main)
        self.main.dirNodesHierarchy, self.main.dirNodes = self.main.computeSpec.getDirHierarchy(self.main.dirList)
        self.main.numLeafDirs = len(self.main.dirNodesHierarchy[-1])
        self.main.createAllViews()
        
        for k, v in roleCompactNodePos.iteritems():
            for r in self.main.roleCompactNodes:
                if r.name == k:
                    r.relativeX, r.relativeY = v[0], v[1]
        
        for k, v in roleNodePos.iteritems():
            for r in self.main.roleNodes:
                if r.name == k:
                    r.relativeX, r.relativeY = v[0], v[1]
        
        for k, v in freeuserNodePos.iteritems():
            usernode = UserNode(k, self.main)
            self.main.userNodes.append(usernode)
            self.main.scene.addItem(usernode)
            usernode.relativeX, usernode.relativeY = v[0], v[1]
            usernode.setPos(v[0]*self.main.scene.sceneRect().width(), v[1]*self.main.scene.sceneRect().height())
                    
        for k, v in dirNodePos.iteritems():
            for r in self.main.dirNodes:
                if r.dir == k:
                    r.relativeX, r.relativeY = v[0], v[1]
                    